1

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:integer

rake 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?

3
  • 1
    What you have there is single table inheritance api.rubyonrails.org/classes/ActiveRecord/Inheritance.html Commented Oct 2, 2015 at 19:33
  • can you show us the code that actually adds the 'field' you can't see (show the first few lines of your Student model for example) and maybe a little more of the User model, so we can see if its activerecord or just a plain ruby class. Commented Oct 2, 2015 at 20:21
  • @Phil - I tried adding one more field through migration, still I don't see any field added to Student table, can you tell me where am I going wrong? Commented Oct 3, 2015 at 3:20

1 Answer 1

3

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:

enter image description here

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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.