构建方法的不同行为

时间:2015-05-27 16:21:48

标签: ruby-on-rails ruby-on-rails-4 activerecord associations

我试图实施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>]>

1 个答案:

答案 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

所以很明白为什么他们的:构建方法不同,文档在这里

http://aima-java.github.io/aima-java/aima3e/javadoc/aima-core/aima/core/probability/mdp/impl/MDP.html

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">]>

第二种方式,父母知道它有孩子,所以当它保​​存时,它会拯救它的孩子。我想是这样的。