Ruby on rails 构建方法的不同行为

Ruby on rails 构建方法的不同行为,ruby-on-rails,ruby-on-rails-4,activerecord,associations,Ruby On Rails,Ruby On Rails 4,Activerecord,Associations,我试图实现一种方法,但在拯救父母时遇到了一个问题:孩子们失踪了 当我在关系上调用我的方法时,一切正常,比如parent.childs.first\u或_build(名称:“Foo”);家长,救救我而当我执行parent.childs.where(名称:'Foo')时,什么也不会发生;家长,救救我 主要目的是提出一种类似于的行为。例如,首先\u或\u create应用于查询结果。(不要告诉我有关。首先\u或\u初始化!) 有什么想法吗 示例: # this is not working :( 2.

我试图实现一种方法,但在拯救父母时遇到了一个问题:孩子们失踪了

当我在关系上调用我的方法时,一切正常,比如
parent.childs.first\u或_build(名称:“Foo”);家长,救救我而当我执行
parent.childs.where(名称:'Foo')时,什么也不会发生;家长,救救我

主要目的是提出一种类似于
的行为。例如,首先\u或\u create
应用于查询结果。(不要告诉我有关
。首先\u或\u初始化
!)

有什么想法吗

示例:

# 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>]>
#这不起作用:(
2.times{i|parent.childs.where(名称:“child{i}”).build{c|c.age=42};parent.childs
=> #
#虽然这是
2.times{i | parent.childs.build{c | c.name=“#{child#{i}”c.age=42};parent.childs
=> #

对不起,我不理解关于first\u或\u构建方法的部分,所以我将只讨论那里的示例

首先,我们知道parent.childs.where(名称:“child{i}”)和parent.childs在不同的类中

    parent.children.where(name: "child").class
    #=>  Child::ActiveRecord_AssociationRelation

    parent.children.class
    #=>  Child::ActiveRecord_Associations_CollectionProxy
所以很清楚为什么他们的:构建方法不同,文档在这里

我将在这里表达我的观点。 当您使用ActiveRecord\u AssociationRelation构建新的子对象时,它将初始化一个新的子对象,并设置其父对象\u id,但它只是一个子对象。此时,当您执行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 []>
parent.children.where(名称:“child1”).build({age:1})
#=> 
父母、子女
#=> 
parent.save#=>true
parent.children.reload
#=> 
但是,当您使用ActiveRecord\u Associations\u CollectionProxy时,它将初始化一个新的子对象,并将自身附加到父对象,因此当您执行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">]>
parent.children.build({name:“child2”,年龄:2})
#=>   
parent.save#=>true
parent.children.reload
#=> 

第二种方法是,父对象知道它有子对象,所以当它保存时,它会保存它的子对象。我想就是这样。

当然,在这个示例中有两个类。我不明白为什么这两个方法都实例化了新的
子对象,而在保存
父对象时,只有第一个方法允许保存新的
子对象在这两种情况下,当打印新的子对象时,您可以看到它们包含父对象的id。它们都只是新的子对象,即使包含父对象的id,它们也没有写入数据库。但第二种方式是,父对象将知道它有子对象,因此当父对象保存时,它将同时保存其子对象。