Reputation:
How can I define a Person model so that any Person can be assigned as the parent of another Person (as demonstrated in the Rails console below)? What columns would you need to define in the migration creating the table for Person?
irb(main):001:0> john = Person.create(name: "John")
irb(main):002:0> jim = Person.create(name: "Jim", parent: john)
irb(main):003:0> bob = Person.create(name: "Bob", parent: john)
irb(main):004:0> john.children.map(&:name)
=> ["Jim", "Bob"]
I unserstand than the answer is something around
class People < ActiveRecord::Base
has_many :children, class_name: "People", foreign_key: "parent_id"
belongs_to :parent, class_name: "People" #Question HERE? how to deal with belong_to more than one?
end
class AddXXTOXXX <ActiveRecord::Migration
def change
create_table :peoples do |t|
t.add_column :name, string
t.add_column :parent, string
t.references :parent, index: true
t.timestamps
end
end
end
But what confused me is that everyone has two parents(mom and daddy), so does belongs_to still work in this case of scenario ?
Upvotes: 0
Views: 151
Reputation: 36860
No, if you have multiple parents who can have multiple children, belongs_to
is not appropriate.
You want has_many through:...
which will use a join table... you can call it whatever you want but relationships
seems appropriate.
Also, change your People
class into Person
class to follow rails conventions.
class Person < ActiveRecord::Base
has_many :ancestors, class_name: 'Relationship', foreign_key: :child_id
has_many :descendants, class_name: 'Relationship', foreign_key: :parent_id
has_many :parents, through: :ancestors, class_name: 'Person', foreign_key: :parent_id
has_many :children, through: :descendants, class_name: 'Person', foreign_key: :child_id
end
You can store additional information in the 'Relationship' table, if you want, such as "mother" or "father" and "son" or "daughter"... although that may be better inferred from Person sex if that exists.
Upvotes: 1