Reputation: 15778
I have a user table, and have a role column, that identify their role. Now, I want to add a "Student" table, that have the student's student number, and I also want to add a "Teacher", to store the teacher's salary.
Both the Student and Teacher are the subclass of User. Now, I added a role column already in the User table, "T" = Teacher, and "S" = Student. Now, I want to add "Student" and "Teacher" in the database. What should I do? Generate scaffold or migration only? Also, it is necessary to modify my models? or I just need to modify the controller only??
Thank you.
Upvotes: 0
Views: 270
Reputation: 18978
As nuclearsandwich said, this is a situation that calls for rails STI (single table inheritance), not polymorphic associations.
Just to highlight the difference:
1) Singe table inheritance is used when you have different models that are very similar to each other with minor differences. STI lumps all models in the same database table, with fields (columns) for all the models that use this table. There is also a "type" field which indicates which model this record belongs to.
Your case is a perfect example of STI. You have user, student, and teacher models, they share a lot of common fields and functionality, you just want an extra field for the student and the teacher.
2) Polymorphic association is used when you have a model that will be associated with different models. For example, imagine you have an "Address" model. Also you have a "Company" and a "User" model, both of which can have an address.
In your Address model, you can specify
belongs_to :user
belongs_to :company
And then make sure if the address belongs to a company not to call address.user and vice-versa. However, a better way to do it would be through a polymorphic association. In your address model you do
belongs_to :addressable, :polymorphic => true
and in your user and company model you add
has_one :address, :as => :addressable
This allows the address model to polymorph (literally: transform into many) its association, and be connected with multiple different models through a single association.
Upvotes: 0
Reputation: 455
This sounds more like a job for Rails' single table inheritance. It's really easy to use. Instead of using a separate table to store roles. Inherit your student and teacher models from User. for example:
User < ActiveRecord::Base; ... end
Student < User; ... end
Teacher < User; ... end
Rails automatically creates a type column and stores the class there.
User.all
will return all users Student.all
will return users where the type is matches Student and Teacher.all
will do the same for all teachers.
You can read more about single table inheritance at the ActiveRecord documentation, and here.
Upvotes: 1