我有一个属于和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并选择父母的集合。
有什么想法吗?
答案 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 :children
和has_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
我认为这是更好的方式...