Создайте связь «многие ко многим» для более 2 классов через класс отношений - PullRequest
0 голосов
/ 06 мая 2011

Я использую Ruby on Rails 3, и я хотел бы установить связь «многие ко многим» для более 2 классов через класс отношений.

Например, у меня есть:

class RelationshipGroup < ActiveRecord::Base # This is the relationship class

  # Maybe the Schema Information should be the following:
  #
  # Table name: RelationshipGroup
  #
  # id    : integer
  # dog_id: integer
  # cat_id: integer
  # cow_id: integer

  ...
end 

class Dog < ActiveRecord::Base
  ...
end 

class Cat < ActiveRecord::Base
  ...
end 

class Cow < ActiveRecord::Base
  ...
end 

В приведенном выше примере я хотел бы установить эти ассоциации, чтобы можно было выполнить поиск с использованием класса RelationshipGroup и чтобы я мог получить всех животных, принадлежащих к группе. Я знаю, как использовать ассоциацию has_many :through для 2 классов, но не для более 2. Таким образом, можно сделать это (возможно, мне придется использовать расширение ассоциации или метод класса чтобы достичь этого?)? Если да, то как мне написать код для приведенного выше примера?

1 Ответ

1 голос
/ 06 мая 2011

Вы можете использовать полиморфную ассоциацию через таблицу соединений.

class RelationshipGroup < ActiveRecord::Base # This is the relationship class
  has_many :memberships
  has_many :members, :through => :memberships
end 

class Membership
  #fields - relationship_group_id, member_id, member_type
  belongs_to :relationship_group
  belongs_to :member, :polymorphic => true
end

class Dog < ActiveRecord::Base
  has_many :memberships, :as => :member
  has_many :relationship_groups, :through => :memberships
end 

class Cat < ActiveRecord::Base
  has_many :memberships, :as => :member
  has_many :relationship_groups, :through => :memberships    
end 

class Cow < ActiveRecord::Base
  has_many :memberships, :as => :member
  has_many :relationship_groups, :through => :memberships    
end 

Чтобы пойти немного дальше, было бы хорошо высушить это, перенеся ассоциации (которые все идентичны) в модуль:

#in lib/member.rb
module Member
  def self.included(base)
    base.class_eval do 
      has_many :memberships, :as => :member
      has_many :relationship_groups, :through => :memberships   
    end    
  end     
end 

class RelationshipGroup < ActiveRecord::Base # This is the relationship class
  has_many :memberships
  has_many :members, :through => :memberships
end 

class Membership
  #fields - relationship_group_id, member_id, member_type
  belongs_to :relationship_group
  belongs_to :member, :polymorphic => true
end

class Dog < ActiveRecord::Base
  include Member
end 

class Cat < ActiveRecord::Base
  include Member 
end 

class Cow < ActiveRecord::Base
  include Member
end 
...