Railsで比較的新しく、名前、性別、father_id、mother_id(2つの親)を持つ単一のPersonモデルで非常に単純な家族「ツリー」をモデル化しようとしています。以下は基本的に私が欲しいものです実行しますが、has_manyで:childrenを繰り返すことはできません(最初のものが上書きされます)。
class Person < ActiveRecord::Base
belongs_to :father, :class_name => 'Person'
belongs_to :mother, :class_name => 'Person'
has_many :children, :class_name => 'Person', :foreign_key => 'mother_id'
has_many :children, :class_name => 'Person', :foreign_key => 'father_id'
end
2つの外部キーでhas_manyを使用する簡単な方法、またはオブジェクトの性別に基づいて外部キーを変更する方法はありますか?または、完全に別の/より良い方法がありますか?
ありがとう!
IRCで動作すると思われる簡単な答えが見つかりました(レーダーのおかげです):
class Person < ActiveRecord::Base
belongs_to :father, :class_name => 'Person'
belongs_to :mother, :class_name => 'Person'
has_many :children_of_father, :class_name => 'Person', :foreign_key => 'father_id'
has_many :children_of_mother, :class_name => 'Person', :foreign_key => 'mother_id'
def children
children_of_mother + children_of_father
end
end
Kenzie の答えを改善するために、Person#children
お気に入り:
def children
children_of_mother.merge(children_of_father)
end
詳細は this answer を参照してください
Personモデルで使用されるnamed_scopesはこれを行います:
class Person < ActiveRecord::Base
def children
Person.with_parent(id)
end
named_scope :with_parent, lambda{ |pid|
{ :conditions=>["father_id = ? or mother_id=?", pid, pid]}
}
end
:has_oneを使用して、必要な関係を実現できると思います。
class Person < ActiveRecord::Base
has_one :father, :class_name => 'Person', :foreign_key => 'father_id'
has_one :mother, :class_name => 'Person', :foreign_key => 'mother_id'
has_many :children, :class_name => 'Person'
end
仕事が終わったら、この回答を確認して編集します。 )
この問題にはスコープを使用することを好みます。このような:
class Person < ActiveRecord::Base
belongs_to :father, :class_name => 'Person'
belongs_to :mother, :class_name => 'Person'
has_many :children_of_father, :class_name => 'Person', :foreign_key => 'father_id'
has_many :children_of_mother, :class_name => 'Person', :foreign_key => 'mother_id'
scope :children_for, lambda {|father_id, mother_id| where('father_id = ? AND mother_id = ?', father_id, mother_id) }
end
このトリックにより、使用インスタンスなしで子供を簡単に取得できます。
Person.children_for father_id, mother_id
Rails(3.2)の Associations and(multiple)foreign keys)への私の答え:モデルでのそれらの記述方法とマイグレーションの記述方法 はあなたにぴったりです!
あなたのコードについては、ここに私の変更があります
class Person < ActiveRecord::Base
belongs_to :father, :class_name => 'Person'
belongs_to :mother, :class_name => 'Person'
has_many :children, ->(person) { unscope(where: :person_id).where("father_id = ? OR mother_id = ?", person.id, person.id) }, class_name: 'Person'
end
だから何か質問?
記載されている一般的な質問(「複数の外部キーを持つhas_many」)の解決策ではありませんが、人は母親または父親のどちらかである可能性がありますが、両方ではない場合、gender
列を追加して、と
has_many :children_of_father, :class_name => 'Person', :foreign_key => 'father_id'
has_many :children_of_mother, :class_name => 'Person', :foreign_key => 'mother_id'
def children
gender == "male" ? children_of_father : children_of_mother
end
同じ機能を探していましたが、配列を返したくないがActiveRecord::AssociationRelation
の場合は、<<
の代わりに+
を使用できます。 ( ActiveRecordのドキュメントを参照 )
class Person < ActiveRecord::Base
belongs_to :father, :class_name => 'Person'
belongs_to :mother, :class_name => 'Person'
has_many :children_of_father, :class_name => 'Person', :foreign_key => 'father_id'
has_many :children_of_mother, :class_name => 'Person', :foreign_key => 'mother_id'
def children
children_of_mother << children_of_father
end
end