Tattat
Tattat

Reputation: 15778

What should I do to make a Polymorphic Relationships in RoR?

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

Answers (2)

Faisal
Faisal

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

nuclearsandwich
nuclearsandwich

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

Related Questions