views:

28

answers:

2

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.

+1  A: 

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.

nuclearsandwich
Any other files that I need to edit?
Tattat
Well, you don't need the role column anymore. You can get rid of it with a new migration. But for STI to work you don't need anything else. You can have even have a UsersController for admin purposes and use separate StudentsController and TeachersController for specific actions.
nuclearsandwich
Well, I added a teacher scaffold, and did the db:migrate, but I go to http://localhost:3000/teachers/new, but it got an error, should I also modify the controller instead of modify the model only?
Tattat
Make sure your Teacher model inherits from User instead of ActiveRecord::Base like the one in my example.
nuclearsandwich
A: 

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.

Faisal