Rails:建模复杂的关联,以适应动物世代之间的现实世界关系

时间:2011-10-17 03:45:36

标签: ruby-on-rails associations ruby-on-rails-3.1

使用Rails 3.1.1

我正在塑造动物(个体狗)和Litters(后代群体)之间的关联。它变得复杂,因为一只动物出生在一堆垃圾 可以生育许多窝(作为母亲 一位父亲。

以下是我的架构的相关部分:

ActiveRecord::Schema.define do

  create_table "animals", :force => true do |t|
    ...
    t.integer  "litter_id"
    t.string   "sex"
    ...
  end

  create_table "litters", :force => true do |t|
    ...
    t.integer  "father_id"
    t.integer  "mother_id"
    ...
  end
end

以下是适当的模型,我认为可以作为协会使用:

class Animal < ActiveRecord::Base
  ...
  belongs_to :litter
  has_many   :litters, :foreign_key => :father_id
  has_many   :litters, :foreign_key => :mother_id
  has_one    :father,  :through => :litter, :foreign_key => :father_id
  has_one    :mother,  :through => :litter, :foreign_key => :mother_id
  ...
end

class Litter < ActiveRecord::Base
  ...
  has_many   :animals
  belongs_to :father, :class_name => 'Animal'
  belongs_to :mother, :class_name => 'Animal'    
  ...
end

如果我在各自的模型中加倍belongs_tohas_many关联,我是否会遇到问题?如果是这样,我该如何正确建模这些关联?


更新: 如下面的评论所述,我正在使用Litter模型跟踪该垃圾中每个动物共有的10个属性。这个软件将由狗饲养员运行,因此Litter本身就是一个相关的单位,从几个角度来看,当涉及到在视图中显示数据时,它将承担很多权重(超出父/子关系)。

2 个答案:

答案 0 :(得分:0)

你应该能够将所有的狗都视为动物。

每只动物都会这样(未经测试):

belongs_to :mother, :class_name => "Animal", :foreign_key => "mother_id"
belongs_to :father, :class_name => "Animal", :foreign_key => "father_id"
has_many :children, :through => :animals # not sure if you need a foreign key specification here

动物表:

id | mother_id | father_id 

您跟踪的最古老的祖先不会有父母,因此他们的mother_idfather_id将为零。

我可以看到跟踪litter_id的唯一原因是跟踪兄弟姐妹,这可能是你需要的。在这种情况下,您可以将垃圾作为自己的对象,如您的示例所示,或者您可以执行简单的检查,如:

class Animal < ActiveRecord::Base
  ...

  def is_sibling_of(animal)
     self.mother == animal.mother
  end

  ...    
end

...或对象scope(在Rails3之前称为named_scope):

class Animal < ActiveRecord::Base
  ...

  scope :siblings, lambda {|animal| {:conditions => ["id not in (?) AND mother_id = ?", animal.id, animal.mother.id} }

  ...
end

这会给你一份指定动物的所有兄弟姐妹的清单,不包括动物本身。

答案 1 :(得分:0)

不知道任何Ruby,Rails或ActiveRecord,我仍然认为你需要一个Graph库(数据结构而不是图片)和一个为你存储它的持久层。 Here是一个Ruby Graph库,持久性就在你身上。