Рельсы: моделирование сложных ассоциаций, чтобы соответствовать реальным отношениям между поколениями животных - PullRequest
1 голос
/ 17 октября 2011

Использование рельсов 3.1.1

Я моделирую ассоциации между животными (отдельными собаками) и пометами (группами потомства).Это усложняется тем, что оба животных рождаются в помете и могут родить много пометов (как мать или отец).

Вот соответствующие части моей схемы:

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_to и has_many в их соответствующих моделях?Если да, как я могу правильно смоделировать эти ассоциации?


ОБНОВЛЕНИЕ: Как уже упоминалось в комментарии ниже, я использую модель мусора для отслеживанияоколо 10 атрибутов, которые являются общими для каждого животного в этом помете.Это программное обеспечение будет запускаться собаководами, поэтому помет сам по себе является подходящей единицей с нескольких точек зрения и будет иметь большой вес (помимо отношений между родителями и детьми), когда дело доходит до отображения данных в представлениях.

Ответы [ 2 ]

0 голосов
/ 17 октября 2011

Не зная ни Ruby, ни Rails, ни ActiveRecord, все же я думаю, что вам нужна библиотека Graph (структура данных, а не картинка) и постоянный слой, который хранит ее для вас. Здесь - библиотека Ruby Graph, настойчивость на вас.

0 голосов
/ 17 октября 2011

Вы должны иметь возможность просто относиться ко всем собакам как к животным.

Каждое животное пойдет примерно так (не проверено):

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_id и father_id будут равны нулю.

Единственная причина, по которой я могу отслеживать отслеживание litter_idэто следить за братьями и сестрами, которые могут быть чем-то, что вам нужно.В этом случае вы можете сделать так, чтобы мусор был его собственным объектом, как в вашем примере, или вы можете сделать простую проверку, например:

class Animal < ActiveRecord::Base
  ...

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

  ...    
end

... или объект scope (был назван named_scope до Rails3):

class Animal < ActiveRecord::Base
  ...

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

  ...
end

Что даст вам список всех братьев и сестер указанного животного, кроме самого животного.

...