【问题标题】:How should I model horse pedigrees in rails?我应该如何在 Rails 中为马谱系建模?
【发布时间】:2013-02-09 23:17:49
【问题描述】:

我需要使用 rails/activerecord 为最多 5 或 6 代马谱系建模。我在这里对堆栈和网络进行了研究,并最终利用article 作为我方法的基础。这是我想出的。

两种型号:

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

抱歉,问题很长,感谢您的帮助。

【问题讨论】:

    标签: ruby-on-rails-3 activerecord associations


    【解决方案1】:

    我可能会开始:

    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
    

    【讨论】:

    • 感谢您的反馈。所以听起来你不认为我需要sire_horse_relationship和dam_horse_relationship。
    • 我会尝试从最简单的关系开始,然后在最后添加您可能需要的所有关系之前尝试它们。在我看来,额外的关系代表了几代人,我认为这些关系将通过递归关系存储(不确定是否需要额外的属性)。
    • 这可能会有所帮助:stackoverflow.com/q/5109893/631619 和 vhttp://stackoverflow.com/q/3029227/631619 如果你想要一个自引用关系,你需要 ..._id 和 ..._type字段。
    • 感谢您的额外参考。您对仅使用 Horse 模型完成这一切有什么想法。我相信它是可行的,我可以完全了解每种方法的优缺点。
    • 我认为那是最好的。我还会考虑一个谱系模型,其中包括指向马的 child_horse_id 和 parent_horse_id 的外键。
    【解决方案2】:

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

      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)
    

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

    我认为,与直接在 Horse 模型中使用sire_id 和 dam_id 相比,拥有两个模型(Horse 和 Pedigree)的方法提供了更多的灵活性。这种方法将使我能够更轻松地创建像@horse.uncle、@horse.aunt 这样的方法。我相信直接在 Horse 模型中使用sire_id 和 dam_id 会更困难。

    完成此任务的最受欢迎的 gem 似乎是 ancestry。作者通过在感兴趣的模型中添加祖先列来实现这一点,而且更简单。这是一个非常好的解决方案,绝对值得一试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-17
      • 1970-01-01
      • 2020-06-16
      • 2015-09-25
      • 2011-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多