# Modeling many types of users

**URL:** <https://www.ruby-forum.com/t/modeling-many-types-of-users/112182>\
**Category:** Rails\
**Created:** [August 16, 2007, 4:13am UTC](https://www.ruby-forum.com/t/modeling-many-types-of-users/112182 "2007-08-16T04:13:48Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![snacktime](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7feea3/32.png) [@snacktime](https://www.ruby-forum.com/u/snacktime)\
**Post date:** [August 16, 2007, 4:13am UTC](https://www.ruby-forum.com/t/modeling-many-types-of-users/112182/1 "2007-08-16T04:13:48Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![snacktime](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7feea3/32.png) [@snacktime](https://www.ruby-forum.com/u/snacktime)\
**Post date:** [August 16, 2007, 5:33am UTC](https://www.ruby-forum.com/t/modeling-many-types-of-users/112182/2 "2007-08-16T05:33:57Z")

</div>

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-1/)  
[http://daveastels.com/2006/08/29/role-based-authentication-from-rails-recipes-part-2/](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!

---

<div class="post-metadata">

**Author:** ![snacktime](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7feea3/32.png) [@snacktime](https://www.ruby-forum.com/u/snacktime)\
**Post date:** [August 16, 2007, 5:47am UTC](https://www.ruby-forum.com/t/modeling-many-types-of-users/112182/3 "2007-08-16T05:47:58Z")

</div>

On 8/16/07, snacktime [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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

---

<div class="post-metadata">

**Author:** ![snacktime](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7feea3/32.png) [@snacktime](https://www.ruby-forum.com/u/snacktime)\
**Post date:** [August 16, 2007, 5:12pm UTC](https://www.ruby-forum.com/t/modeling-many-types-of-users/112182/4 "2007-08-16T17:12:25Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![snacktime](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/7feea3/32.png) [@snacktime](https://www.ruby-forum.com/u/snacktime)\
**Post date:** [August 16, 2007, 6:12pm UTC](https://www.ruby-forum.com/t/modeling-many-types-of-users/112182/5 "2007-08-16T18:12:36Z")

</div>

has\_many\_polymorphs to the rescue 🙂  
[http://blog.evanweaver.com/pages/code#polymorphs](http://blog.evanweaver.com/pages/code#polymorphs)

On 8/16/07, snacktime [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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!

- Pratik  
[http://m.onkey.org](http://m.onkey.org)
