Multiple roles of a user with STI

Folks,

I have setup Single Table Inheritance with my User model. Now the user can have multiple roles. In my situation (a school app) the user can be a Teacher (through which I want to access the students, grades etc) and the same user can also be a Parent (through which I want to access the children info). In STI, the type column in the user table can store only one type i.e. either Parent or Teacher. So when this user logs in and I want to access students at one time and children at another - through Teacher or Parent models respectively.

The model hierarchy is as below -

class User < ActiveRecord::Base end

class Parent < User # relationships and functionality to work on children end

class Teacher < User # relationships and functionality to work on students and grades etc end

Searched around but can't find anything on this. It doesn't look like I can accomplish this through STI. However I have the Parent and Teacher functionality setup through these STI models. What is the best way to model/enable this?

Thanks for any pointers.

-S

I did this with a pretty gross hack on an app a while back - the roles were designed to be mutually exclusive, then the client changed their mind 4+ months in. The trick was to disambiguate the records by fiddling with the email - in my case, I added the (underscored) role to the email. So bob@example.com who was (for instance) a Parent and a Teacher would have two records:

Parent: email_address = 'bob+parent@example.com' Teacher: email_address = 'bob+teacher@example.com'

I had to tweak the code that handled login, and add some callbacks to keep the records in sync (as well as always de-mangling the emails for display).

From the UI side, I added a screen to allow users to switch between each of the roles; for the app, this made sense as each role had a somewhat different set of navigation tabs + view permissions.

Not the cleanest solution, but it beat rewriting everything to accommodate multiple roles per user.

--Matt Jones

skt wrote in post #975891:

Folks,

I have setup Single Table Inheritance with my User model. Now the user can have multiple roles.

[...]

Time to get rid of the STI, then! Do User habtm :roles instead.

Best,

Matt Jones wrote in post #975916:

# relationships and functionality to work on students and grades etc end

Searched around but can't find anything on this. It doesn't look like I can accomplish this through STI. However I have the Parent and Teacher functionality setup through these STI models. What is the best way to model/enable this?

I did this with a pretty gross hack on an app a while back - the roles were designed to be mutually exclusive, then the client changed their mind 4+ months in. The trick was to disambiguate the records by fiddling with the email - in my case, I added the (underscored) role to the email. So bob@example.com who was (for instance) a Parent and a Teacher would have two records:

Parent: email_address = 'bob+parent@example.com' Teacher: email_address = 'bob+teacher@example.com'

That's a dreadful idea. You're essentially keeping the user from meaningfully pluscoding his e-mail address.

I had to tweak the code that handled login, and add some callbacks to keep the records in sync (as well as always de-mangling the emails for display).

From the UI side, I added a screen to allow users to switch between each of the roles; for the app, this made sense as each role had a somewhat different set of navigation tabs + view permissions.

Not the cleanest solution, but it beat rewriting everything to accommodate multiple roles per user.

No it didn't. That's a dreadful hack, and you should rip it out and do it right (which would probably have taken no longer...)

--Matt Jones

Best,

Thanks for the feedback folks. I think I resolved that with a simple tweak by making Teacher inherit from Parent as this is an "is-a" relationship.

class Teacher < Parent # Gives access to Parent functionality end

The type column in User table says "Teacher" and the User (Teacher) object has access to Parent's functionality. Any potential pitfalls that I may not be seeing with this?

Thanks, -S