如何与同一对象共享两个不同的关联?

时间:2012-08-15 14:35:07

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

我有一个属于和has_many的关系。

孩子属于父母 父母有很多孩子。

但是,我还有另一种方式,父母可以有一个孩子,这是通过我用来创建父母类型的分组的join_table。

这是我对如何做到这一点的可怕猜测:

# child.rb

belongs_to :parent
belongs_to :parent_group, :dependent => :destroy
delegate :parent, :to => :parent_group

# parent.rb

has_many :children
has_many :children, through: :parent_groups

注意,我实际上并没有使用这些命名约定。这些只是改变了以保持我的工作匿名。

然后我的迁移看起来像这样:

class CreateParentGroup < ActiveRecord::Migration
  def self.up
    create_table :parent_groups do |t|
      t.integer :parent_id
      t.timestamps
    end
    add_column :child, :parent_group_id, :integer
  end

所以我的目标是,如果我键入Parent.find(n).children,它将返回通过 parent_group的Child对象以及与其直接相关的任何子对象。

反之亦然,如果我选择Child.find(n).parent,它会选择它的父母是否通过一个父组。

最后,我将能够选择parent_groups并选择父母的集合。

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

首先,如果您正在谈论连接表,那么我认为此表的架构设置不太正确。它应该是这样的:

class CreateParentGroup < ActiveRecord::Migration
  def self.up
    create_table :parent_groups do |t|
      t.integer :parent_id
      t.integer :child_id
      t.timestamps
    end
  end
end

所以,现在你的桌子parent_groups可以容纳许多父母的孩子。

至于在模型中设置关联:您不能/不应该使用相同名称命名两个不同的关联。因此,您无法在一个模型中同时执行has_many :childrenhas_many :children, :through => :parent_groups。如果您通过Parent.find(n).children访问子项,则会导致Rails不知道要使用哪个关联。

我会做这样的事情:

class Parent < AR
  has_many :regular_children, :class_name => 'Child'
  has_many :group_children, :class_name => 'Child', :through => :parent_groups

  # implement a method that combines them both
  def children
    regular_children + group_children
  end
end

class Child < AR
  belongs_to :parent
  belongs_to :parent_group, :dependent => :destroy

  # forget the delegate, otherwise your invoke of Child.find(n).parent always
  # gets delegated to parent_group which is/can be wrong due to data
end

我认为这是更好的方式...