2

rails / activerecordを使用して、最大5世代または6世代の馬の血統をモデル化する必要があります。私はここでスタックとWebで調査を行い、最終的にこの記事をアプローチの基礎として利用しました。これが私が思いついたものです。

2つのモデル:

Horse has the following attributes id and horse_name
Pedigree has: id, parent_id and horse_id.

そして、次の関連付け:

has_many  :parent_horse_relationships, :class_name => "Pedigree", :foreign_key => :horse_id, :dependent => :destroy

has_one  :sire_horse_relationship, :class_name => "Pedigree", :foreign_key => :horse_id, :conditions => "horse_gender = 'Male'

has_one  :dam_horse_relationship, :class_name => "Pedigree", :foreign_key => :horse_id, :conditions => "horse_gender = 'Female'

has_many  :parents, :through => :parent_horse_relationships, :source => :parent 

has_one  :sire, :through => :sire_horse_relationship,:source => :parent

has_one  :dam, :through => :dam_horse_relationship,:source => :parent

has_many  :horse_parent_relationships, :class_name => "Pedigree", :foreign_key => :parent_id, :dependent => :destroy

has_many  :progenies, :through => :horse_parent_relationships, :source =>  :horse

このアプローチは近いですが、ダムまたは種雄牛が親ではなく馬に適用されているかどうかを判断するための私の条件のようです。したがって、特定の馬が男性の場合、horse.sireは機能しますが、horse.damは機能しません。その逆も同様です。基本的な機能が機能するようになったら、血統全体、祖父母、兄弟、子孫などを取得するためのメソッドを追加したいと思います。

質問:

  1. 父と母の両方が機能するように、どうすれば馬ではなく親に性別条件を適用できますか。

  2. 私が採用したアプローチは実行可能ですか、それともこれを達成するためのよりエレガントで効率的な方法がありますか。

  3. その他の提案やガイダンスをいただければ幸いです。

長い質問をお詫びし、あなたの助けに感謝します。

4

2 に答える 2

2

私は始めるかもしれません:

has_one  :sire, :class_name => "Pedigree", :foreign_key => :horse_id, :conditions => "horse_gender = 'Male'
has_one  :dam, :class_name => "Pedigree", :foreign_key => :horse_id, :conditions => "horse_gender = 'Female'

has_many  :parent_horse_relationships, :class_name => "Pedigree", :foreign_key => :horse_id, :dependent => :destroy
has_many  :parents, :through => :parent_horse_relationships, :source => :parent 

has_many  :progenies, :through => :horse_parent_relationships, :source =>  :horse
于 2013-01-31T01:34:16.650 に答える
0

私はこれに多くの時間を費やすことになりましたが、最終的に私の要件を満たすソリューションを思いつきました。最終的に機能したアソシエーションは次のとおりです。

  has_many :parent_horse_relationships, :class_name => "Pedigree", :foreign_key => :horse_id, :dependent => :destroy

  has_many :parents, :through => :parent_horse_relationships, :source => :parent do 
    def dam_relationship
      owner = self.proxy_association.owner
      owner = owner.parents.where(:horse_gender => "Female")
      where('pedigrees.parent_id = ?', owner)
    end

    def sire_relationship
      owner = self.proxy_association.owner
      owner = owner.parents.where(:horse_gender => "Male")
      where('pedigrees.parent_id = ?', owner)
    end
  end

  def dam
    parents.dam_relationship
  end

  def sire
    parents.sire_relationship
  end

質問への回答:

私はassociation_proxyと単純なラッパーを使用して性別条件を適用しました。私はdam_relationshipと対応するsire_relationshipを作成し、それらのメソッドをいくつかのdamとsireラッパーメソッドでラップしました。

def dam_relationship
owner = self.proxy_association.owner
owner = owner.parents.where(:horse_gender => "Female")
where('pedigrees.parent_id = ?', owner)
end

def dam
parents.dam_relationship
end

これにより、次のことが可能になります。

@horse.parents, @horse.dam, @horse.sire (not displayed)

下記の祖先の宝石に含まれるほとんどの方法と同様に。少し再帰的にすると、血統全体または関心のある世代数を表示するのはかなり簡単です。

2つのモデル(HorseとPedigree)を使用するアプローチでは、sire_idとdam_idをHorseモデルに直接使用する場合と比較して、柔軟性が向上することにしました。このアプローチにより、@ horse.uncle、@horse.auntなどのメソッドをより簡単に作成できるようになります。これらは、Horseモデルに直接sire_idとdam_idを使用するとさらに難しくなると思います。

これを達成するための最も人気のある宝石は祖先のようです。著者は、対象のモデルに祖先列を追加することで、これをさらに簡単に実現します。その非常に素晴らしいソリューションは間違いなくチェックする価値があります。

于 2013-02-09T15:17:49.823 に答える