这是我的问题的后续跟进: Updating child association in ActiveModel
我正在寻找更新与父母相关的多个儿童记录的标准/正确方法。
假设我有一个父(连接到带有has_many的子表,并且:autosave => true)。
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
但是,
x = Parent.first
c = x.children.first
c.remark = "something"
x.save # => doesn't update c
答案 0 :(得分:2)
您想要ActiveRecord nested_attributes
class Parent
include ActiveModel::Model
accepts_nested_attributes_for :children
end
更新您的孩子并保存父母,您应该完成
编辑:您必须先致电parent.children
:
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
答案 1 :(得分:0)
您可以覆盖保存方法,但我不会这样做。为什么不这样做呢?
def save_with_children
Child.transaction do
children.each do |child|
if child.changed?
child.save
end
end
end
save
end
这应该运行1个查询。如果你有10'000'000个记录,但你没有提到它,可能不会起作用。