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