收到时:
{
parent:{
children_attributes:[
{child1}, {child2}
]
}
}
即将创建child1
个实例,我没有设置parent_id
。我想这是在节省时间设置的。
我该如何处理这个问题:
class Child < ActiveRecord::Base
belongs_to :parent
before_save :do_something
def do_something
# access parent here
# I can't, since parent_id is nil yet
end
end
class Parent < ActiveRecord::Base
has_many :children
accepts_nested_attributes_for :children
end
我是通过相关问题尝试过的:
class Parent < ActiveRecord::Base
has_many :children, inverse_of: :parent
end
但同样的问题。
我试过这个
class Parent
before_save :save_children
attr_accessor :children_attributes
def save_children
children_attributes.all? do |k, attrs|
# tried different things here, this one is the one I expected to work the most
child = Child.new attrs.merge(parent_id: id)
child.save
end
end
我将parent_id添加到子attr_accessible调用。
我错过了什么?
答案 0 :(得分:2)
这个问题的原因是验证了子类中父项的存在。
我基本上从Child对象中删除了这一行,它可以正常工作。
validates :parent, presence: true
但是,根据我的发现,解决此问题的正确方法是使用inverse_of
参数。如果您将其添加到父级的has_many
和孩子的belongs_to
,那么您应该很高兴。
在父母:
has_many :child, inverse_of: :parent
在孩子身上:
belongs_to :parent, inverse_of: :child
答案 1 :(得分:1)
在模型中的has_many声明中设置inverse_of: :model_name
,其中model_name是您的“父”模型。
例如:has_many :product_items, dependent: :destroy, inverse_of: :product
答案 2 :(得分:0)
在你的模型中,你应该能够像这样引用父母:
self.parent_class
因此,例如,如果产品包含许多零件,则在零件模型(part.rb)中,您可以像这样引用产品的属性:
self.product.id
这将返回作为零件父级的产品的id。你可以显然像这样引用父类的任何属性。
这应该适用于子模型中的before_save回调。
此外,您不应该使用上面代码中包含的“inverse_of :: parent”来实现此目的。
要回答关于何时添加父ID的问题,如果您的表单设置正确,则应自动将表单中的参数传递给控制器。
答案 3 :(得分:0)
这可能对您的问题有所帮助:http://guides.rubyonrails.org/association_basics.html#association-callbacks
关联回调不适用于belongs_to
,但适用于has_many
。
class Parent < ActiveRecord::Base
has_many :children, before_add: :do_something
def do_something(child)
# self.id = 1
# child.parent_id = 1
end
end
# parent1 = Parent.find(1)
# parent1.children.create(...)