Ruby on rails activemodel-保存父对象时更新对象的子对象
以下是我的问题: 我正在寻找一种标准/正确的方法来更新与家长相关的多个儿童记录 假设我有一个连接到子表的父表has_many,and:autosave=>trueRuby on rails activemodel-保存父对象时更新对象的子对象,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,以下是我的问题: 我正在寻找一种标准/正确的方法来更新与家长相关的多个儿童记录 假设我有一个连接到子表的父表has_many,and:autosave=>true obj = Parent.first 现在我迭代它的子对象,并更新它们 obj.each.do |child| child.remark = "something" end 我希望在调用obj.save时将子项与父项一起保存,但正如在上一个问题中向我解释的那样,唯一的方法是直接更新它,如下所示: obj.children
obj = Parent.first
现在我迭代它的子对象,并更新它们
obj.each.do |child|
child.remark = "something"
end
我希望在调用obj.save时将子项与父项一起保存,但正如在上一个问题中向我解释的那样,唯一的方法是直接更新它,如下所示:
obj.children.first.remark = "something"
或者保存每个孩子,但这需要一个明确的事务,我认为这里不应该使用它
正确的方法是什么
谢谢
*编辑:
根据此处给出的建议,我将此添加到模型中:
class Parent < ActiveRecord::Base
has_many :children, :inverse_of => :parent,:autosave=>true
accepts_nested_attributes_for :children
你想要ActiveRecord吗
更新您的孩子并保存家长,您应该完成
编辑:您必须先调用parent.children:
您可以覆盖save方法,但我不会这样做。为什么不这样做呢
def save_with_children
Child.transaction do
children.each do |child|
if child.changed?
child.save
end
end
end
save
end
这应该运行1个查询。如果你有1万张唱片,可能就行不通了,但你没有提到这一点。当然。我正在更新这个问题。打电话给x.children成功了。请注意,此处并不真正需要accepts_nested_attributes(接受_nested_属性)-它足以在has_many definitionok nice上设置:autosave=>true,但另一方面,请注意,正如文档所述:请注意:在接受\u nested_属性的每个关联上自动启用:autosave选项。\u用于:这不是一个有效的解决方案。接受\u嵌套的\u属性\u是ActiveRecord的一部分,而不是ActiveModel。那么这是ActiveRecord还是ActiveModel?这似乎是唯一的方法,但奇怪的是,在使用build和我使用的所有其他ORM添加记录时,您不需要它。在事务中包装保存也是嵌套的\u属性\u的作用
class Parent
include ActiveModel::Model
accepts_nested_attributes_for :children
end
irb(main):001:0> x = Parent.first
Parent Load (0.3ms) SELECT "parents".* FROM "parents" ORDER BY "parents"."id" ASC LIMIT 1
=> #<Parent id: 1, created_at: "2013-08-07 21:21:10", updated_at: "2013-08-07 21:21:10">
irb(main):002:0> x.children
Child Load (3.0ms) SELECT "children".* FROM "children" WHERE "children"."parent_id" = ? [["parent_id", 1]]
=> #<ActiveRecord::Associations::CollectionProxy [ ]>
irb(main):003:0> x.children.first.remark = "foo"
=> "foo"
irb(main):004:0> x.save
(0.3ms) begin transaction
SQL (2.3ms) UPDATE "children" SET "remark" = ?, "updated_at" = ? WHERE "children"."id" = 1 [["remark", "foo"], ["updated_at", Wed, 07 Aug 2013 21:33:04 UTC +00:00]]
(0.3ms) commit transaction
=> true
def save_with_children
Child.transaction do
children.each do |child|
if child.changed?
child.save
end
end
end
save
end