Looking for some input on modeling a user system.
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.
Anyone think of a simpler way of doing this?
Chris
I would check out the role-based authentication from Rails Recipe or
you can see a revised (better) version of that recipe here:
http://daveastels.com/2006/08/29/role-based-authentication-from-rails-recipes-part-1/
http://daveastels.com/2006/08/29/role-based-authentication-from-rails-recipes-part-2/
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.
Hope that helps!
On 8/16/07, snacktime [email protected] wrote:
Creating a model for each user type is also problematic for
probably have an abstract UserProfile also to stick methods and
attributes that are common to all profile types.
Anyone think of a simpler way of doing this?
Chris
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.
Cheers
Daniel
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 }
UserTypeA { wierd_attr_1, wierd_attr_2, wierd_attr_3 }
UserTypeB { wierd_attr_A, wierd_attr_B, wierd_attr_C}
UserTypeC { wierd_attr_x, wierd_attr_y, wierd_attr_z }
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.
has_many_polymorphs to the rescue
http://blog.evanweaver.com/pages/code#polymorphs
On 8/16/07, snacktime [email protected] wrote:
authorizing users and handling logins. We also have an access control
attributes that are common to all profile types.
Anyone think of a simpler way of doing this?
Chris
–
Cheers!