I'm amazed at how hard it is to still find a definitive answer to this: it seems so common that I must be looking at it all wrong.
We have Users, who's authorization roles run something like ROLES = %w[admin moderator teacher student banned]
It's commonly recommended to use a ROLES field and Single Table Inheritance to (as here)
class User < ActiveRecord::Base
end
class Student < User
end
class Teacher < User
end
But this puts all the data in one table. What if we have a good bit of data unique to each user type?
student
year:integer
request_id:integer
portfolio_id:integer
status:string
...
teachers
user_id:integer
district:string
school:string
subject1:string
subject2:string
specialty:string
bio:text
...
STI gives things like student.specialty and teacher.portfolio_id, which we don't want and would have to block.
The Ruby Way suggests Abstract Base Model Class to handle separate tables:
class User < ActiveRecord::Base
self.abstract = true
end
class Student < User
end
class Teacher < User
end
Which will allow unique tables for both Student and Teacher. However, he warns, User.find(:all) won't work. Plus, there's the common attributes we wanted, which was the whole point of a User model:
User
username:string
email:string
password:string
role:string
Since there's no User table, there's no common attributes?
Various other answers hint at using :polymorphic => true
, :class_name => 'User'
, or as:
but all explained more like adding a Comments to both a post and an image. Which doesn't seem a good parallel.
I seem to recall at least one language (and maybe a couple OODB's) which simply used the IS-A relationship to inherit attributes.
What's the RAILS way?