ruby on rails 4 - Can't get has_many & belongs_to in same model to work -
it has been while since asked around here. since have started playing around ruby, , can't head around this, decided come here guidance.
i've read quite few examples now, don't find proper path walk solve problem.
the idea following :
you have :
- a family
- a person
their relationship following :
- there 1 person 'head' of family
- every person part of family (be multiple persons or himself in it)
now current validation makes impossible perform this, idea there no such thing family without head, , no person without family. i've tried express following way :
family class
class family < activerecord::base validates :head_id, presence: true belongs_to :head, :class_name => person, foreign_key: 'head_id' has_many :persons end
person class
class person < activerecord::base validates :family_id, presence: true validates :first_name, presence: true belongs_to :family end
would soul kind offer me advice?
the migration has family_id on person-class side, family consists of column being person_id.
family migration
class createfamilies < activerecord::migration def change create_table :families |t| t.integer :head_id t.timestamps null: false end end end
person migration
class createpersons < activerecord::migration def change create_table :persons |t| t.string :first_name t.string :last_name t.integer :age t.integer :family_id t.timestamps null: false end end end
you got circular dependency here. cannot create families nor people. circular dependency indicates there's third element missing. more eloquently , not related .
there 2 kind of membership, head , non-head. once make them obvious in code circular dependency solved.
there few solutions need find 1 fits best. mine.
create membership join table
class family validates :memberships, presence: true, on: :update has_many :memberships has_many :people, through: :membership after_create :create_head_membership private def create_head_membership memberships.create role: 'head' # filled later end end class membership belongs_to :family belongs_to :person end class person has_many :memberships has_one :family, through: :membership # has_many, amrite? validates :memberships, presence: true, on: :update end
the important thing avoid person/family direct manipulation, rather create handle process , wrap in transaction
class god def make_family head_attrs fam, head = nil family.transaction fam = family.create! head = person.create! head_attrs fam.memberships.first.update_attribute! :person_id, head.id end fam end end
Comments
Post a Comment