The user system is for schools. We have many potential types of
users, and we need to be extremely flexible in the design as the
system will be used at different school districts in different states.
Single table inheritance doesn't really work as we would end up with
many attributes that don't apply to one type of user or another.
Creating a model for each user type is also problematic for
authorizing users and handling logins. We also have an access control
model that uses permissions and groups, but I won't go into that here.
So what I was thinking is that we have a simple user model, something
like what is used in acts_as_authenticated.
Then we have a Profile model (couldn't think of a better name) that
contains all the attributes for particular types of users. Attributes
could be a name, email address, school district, courses taught, etc..
So we would have a StudentProfile, TeacherProfile, etc.. We would
probably have an abstract UserProfile also to stick methods and
attributes that are common to all profile types.
You basically model Users, their Roles (student, teacher, admin,
etc.), and then the Rights associated to a particular Role. The
solution is flexible and allows you to control what Roles are allowed
to do at the controllers / actions level.
Without thinking it through completely and really thinking out loud The thought of “mixing” in an active record model into another model might conceptually be schwoit.
Basically delegate the method missing to each mixed in model until something responds. Use after save etc to save the associations etc. What I have in my head is similar to mixing in a module, but your mixing in a persistent model. Perhaps some copious use of with_scope might help.
As I said, I haven’t thought this completely through, but it seems like it would be slow but flexible if it’s possible.
Don't think of user types as a matter of inheritance, think of it as
a property. So, you have generic users and they have relationships
to other tables that give them the desired properties. In fact, you
could make it a polymorphic association. For example:
User { username, password, first_name, last_name, dob }
So user carries the core, common information. The different UserType
{A, B, C} tables carry information specific to that type of user. As
a more concrete example, for one client we modeled invoices and
payments. Each payment can be a credit card payment, check payment,
or electronic transfer. (This affects how refunds are handled when a
payment is canceled.)
An invoice has many payments and each payment has a payment_info
polymorphic reference. That payment_info can be a credit_card_info,
check_info, or transfer_info. If we were to add a new type of
payment (say e-check) we could add an echeck_info to the model fairly
easily. See AWDR2 - pages 346-349.