I've been banging my head against a wall trying to wrap my head around this, so any guidance would be much appreciated...
I want to have a User system setup to reflect the following hierarchy:
User
|- email address
|- password
|- billing information
|- contact information
|- account preferences
|
|=> Agent
|=> - agent-specific information
|=> - has_many Users
|=> - belongs_to Manager
|
|=> Manager
|=> - manager-specific information
|=> - has_many Agents, Users
|
|=> Administrator
|=> - can manage everything
I already have a User
model with Devise and CanCan setup to handle authentication and authorization, so I know how to use roles to restrict the type of user to specific actions, and so forth.
What I'm lost at is how to organize these sub-class relationships both in my Rails code and in the database. As you can see from above, Agent
, Manager
, and Administrator
all share the information contained in User
, but each has additional functionality AND information associated with it.
I've read some about STI, polymorphic associations, and self-referential associations.
If I use STI, the User
table would have to contain fields for all of my [Agent
/Manager
/Administrator
]-specific information, right? That would make my User
table huge, which is something I'd like to avoid. Conversely, if I use polymorphic, then wouldn't I have to duplicate all the common information in User
across all the other types of User
subclass tables?
And to add to my confusion, I can't wrap my head around how the answer to the above question would work with the relationships between the subclasses (as in, that a Manager
has_many Agents
, but both are subclasses of User
...??).
I would really appreciate someone setting me straight on this through a detailed answer that gives due consideration to code readability and data integrity, that explains simply (as if to a Rails newbie) why A is the best approach and why B or n is--by comparison--not a good approach for this situation, and that gives example code to implement the relationships described above. I want to solve this problem, but more importantly, I want to learn why the solution works!