activemodel - 保存父对象时更新对象的子对象

sha*_*ish 5 activerecord ruby-on-rails

这是我的问题的后续: Updating child Association in ActiveModel

我正在寻找标准/正确的方法来更新与父级关联的多个子级记录。

假设我有一个父表(使用 has_many 连接到子表,并且 :autosave=>true)。

obj = Parent.first
Run Code Online (Sandbox Code Playgroud)

现在我迭代它的孩子,并更新它们。

obj.each.do |child|
    child.remark = "something"
end
Run Code Online (Sandbox Code Playgroud)

我希望在调用 obj.save 时将子级与父级一起保存,但正如上一个问题中向我解释的那样,唯一的方法是直接更新它,如下所示:

obj.children.first.remark = "something"
Run Code Online (Sandbox Code Playgroud)

(或者保存每个孩子,但这需要一个显式事务,我认为这里不应该使用)。

实施这个的正确方法是什么?

谢谢!

*编辑:按照此处给出的建议,我已将其添加到模型中:

class Parent < ActiveRecord::Base

     has_many :children, :inverse_of => :parent,:autosave=>true

     accepts_nested_attributes_for :children
Run Code Online (Sandbox Code Playgroud)

但仍然,

x = Parent.first
c = x.children.first
c.remark = "something"
x.save    # => doesn't update c
Run Code Online (Sandbox Code Playgroud)

mde*_*lin 3

你想要ActiveRecord的nested_attributes

class Parent
  include ActiveModel::Model

  accepts_nested_attributes_for :children
end
Run Code Online (Sandbox Code Playgroud)

更新你的孩子并拯救父母,你应该完成

编辑:你必须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
Run Code Online (Sandbox Code Playgroud)

  • 调用 x.children 就成功了。请注意,这里并不真正需要accepts_nested_attributes - 将 :autosave=&gt;true 放在 has_many 定义上就足够了 (2认同)