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

Ruby 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

以下是我的问题:

我正在寻找一种标准/正确的方法来更新与家长相关的多个儿童记录

假设我有一个连接到子表的父表has_many,and: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
你想要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