I have Student model, inheriting User model
class Student < User
if I add new field to Student, its not showing up. All I see is replica of User fields in Student table.
rails g model User email:string name:string gender:boolean
rails g model Student age:integerrake db:migrate
User model :
class User < ActiveRecord::Base
validates :email, :name, presence: true
end
then I replaced
class Student < ActiveRecord::Base with
class Student < User
end
now the :age field is replaced by :email, :name, :gender fields in Student table, I don't have access to :age field anymore
Student should have User fields as well as additional fields of its own.
how do I achieve this?
I think you're getting confused between tables
and models
in Rails.
As mentioned in the comments, you have a Single Table Inheritance setup; you'll have a single users
table which can be extrapolated to different classes (models) using the Type
attribute:
#app/models/user.rb
class User < ActiveRecord::Base
#columns id | type | other | user | attributes | created_at | updated_at
end
#app/models/student.rb
class Student < User
# uses "users" table
def custom_method
#=> Will only appear with @student.custom_method (IE @user.custom_method will not exist)
end
end
This means that you don't have two tables in this instance; Student
will be using the User
table.
If you wish to use custom attributes in the Student
model, you're able to (outlined above). Ultimately, with STI, you have to use the same table for all the inherited models. If you need to add extra attributes, you're going to have to append to the "parent" table.
--
Student should have User fields as well as additional fields of its own
If there are a lot of attributes, you'll have to set up another table to store them, and then associate the two models. It will be messier, but it's better than storing huge amounts of empty cells in a single table:
#app/models/user.rb
class Student < ActiveRecord::Base
has_one :profile
end
#app/models/profile.rb
class Profile < ActiveRecord::Base
belongs_to :student
end
This is how we store our users in some of our apps:
This gives us the ability to call @user.profile.homepage
etc, or if we wanted to delegate it:
#app/models/user.rb
class User < ActiveRecord::Base
has_one :profile
delegate :homepage, to: :profile, prefix: true #-> @user.profile_homepage
end