我应该如何在轨道上对马血统进行建模



我需要使用rails/activerecord对多达5或6代的马血统进行建模。 我在堆栈和网络上进行了研究,并最终将本文用作我方法的基础。这是我想到的。

两种型号:

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. 任何其他建议或指导将不胜感激。

对于这个冗长的问题,我们深表歉意,并感谢您的帮助。

我可能会从:

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

我最终在这个问题上花费了大量时间,但最终提出了一个满足我要求的解决方案。 最终起作用的协会如下:

  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和sear包装器方法中。

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)

以及下面提到的祖先宝石中包含的大多数方法。只需一点递归,就可以相当直接地显示整个谱系或您感兴趣的世代数。

我决定,与直接在马模型中使用sire_id和dam_id相比,拥有两个模型(马和血统)的方法提供了额外的灵活性。这种方法将使我能够更轻松地创建方法,例如@horse.uncle,@horse.aunt。 我相信这些会更困难,直接在 Horse 模型中使用sire_id和dam_id。

实现这一目标最受欢迎的宝石似乎是血统。 作者通过向感兴趣的模型添加祖先列来实现这一目标,并且更简单。这是一个非常好的解决方案,绝对值得一试。

相关内容

  • 没有找到相关文章