我试图实施first_or_build方法,在保存父母时遇到问题:孩子们失踪了。
当我在parent.childs.first_or_build(name: 'Foo'); parent.save!
这样的关系上调用我的方法时,一切都运行良好,而当我parent.childs.where(name: 'Foo').first_or_build; parent.save!
时没有任何事情发生。
主要目标是提出一种类似于.first_or_create
的行为,例如应用于查询结果。 (别告诉我.first_or_initialize
!)
有什么想法吗?
示例:
# this is not working :(
2.times { |i| parent.childs.where(name: "child #{i}").build { |c| c.age = 42 } } ; parent.childs
=> #<ActiveRecord::Associations::CollectionProxy []>
# while this is
2.times { |i| parent.childs.build { |c| c.name = "#{child #{i}"; c.age = 42 } } ; parent.childs
=> #<ActiveRecord::Associations::CollectionProxy [#<Child name: "child 0", age: 42>, #<Child name: "child 1", age: 42>]>
答案 0 :(得分:0)
抱歉,我不会理解有关first_or_build方法的部分,所以我将在那里谈谈这些例子。
首先,我们知道parent.childs.where(名称:&#34;孩子#{i}&#34;)和parent.childs属于不同的类
parent.children.where(name: "child").class
#=> Child::ActiveRecord_AssociationRelation
parent.children.class
#=> Child::ActiveRecord_Associations_CollectionProxy
所以很明白为什么他们的:构建方法不同,文档在这里
ActiveRecord_Associations_CollectionProxy
我会在这里表达我的观点。 当您使用ActiveRecord_AssociationRelation构建新子项时,它将初始化一个新的Child对象,并设置其parent_id,但它只是一个Child对象。在这个时候,当你执行parent.children时,结果是空的。
parent.children.where(name: "child1").build({age: 1})
#=> <Child id: nil, name: "child1", age: 1, parent_id: 1, created_at: nil, updated_at: nil>
parent.children
#=> <ActiveRecord::Associations::CollectionProxy []>
parent.save #=> true
parent.children.reload
#=> <ActiveRecord::Associations::CollectionProxy []>
但是当你使用ActiveRecord_Associations_CollectionProxy时,它会初始化一个新的Child对象,它也会将自己附加到父对象,所以当你执行parent.children时,结果不是空的。
parent.children.build({name: "child2", age: 2})
#=> <Child id: nil, name: "child2", age: 2, parent_id: 1, created_at: nil, updated_at: nil
parent.children
#=> <ActiveRecord::Associations::CollectionProxy [#<Child id: nil, name: "child2", age: 2, parent_id: 1, created_at: nil, updated_at: nil>]>
parent.save #=> true
parent.children.reload
#=> <ActiveRecord::Associations::CollectionProxy [#<Child id: 3, name: "child2", age: 2, parent_id: 1, created_at: "2015-05-28 17:02:39", updated_at: "2015-05-28 17:02:39">]>
第二种方式,父母知道它有孩子,所以当它保存时,它会拯救它的孩子。我想是这样的。