Ruby on rails Rails 3中的Build vs new
在Rails 3中,关联的Ruby on rails Rails 3中的Build vs new,ruby-on-rails,ruby-on-rails-3,associations,Ruby On Rails,Ruby On Rails 3,Associations,在Rails 3中,关联的build方法被描述为与new方法相同,但具有外键的自动分配。直接从文档中: Firm#clients.build (similar to Client.new("firm_id" => id)) 我在其他地方也读过类似的文章 但是,当我使用new时(例如一些公司客户.new没有任何参数),新客户的公司id关联会自动创建。我现在正在控制台中查看结果 我错过什么了吗?这些文件是否有点过时(不太可能)?build和new之间有什么区别?没错,build和new函数在
build
方法被描述为与new
方法相同,但具有外键的自动分配。直接从文档中:
Firm#clients.build (similar to Client.new("firm_id" => id))
我在其他地方也读过类似的文章
但是,当我使用new
时(例如一些公司客户.new
没有任何参数),新客户的公司id
关联会自动创建。我现在正在控制台中查看结果
我错过什么了吗?这些文件是否有点过时(不太可能)?
build
和new
之间有什么区别?没错,build和new函数在通过关联调用时具有设置外键的相同效果。我相信文档这样写的原因是为了澄清正在实例化一个新的客户机对象,而不是一个新的活动记录关系。这与在Ruby中对类调用.new的效果相同。也就是说,文档澄清了在关联上调用build与创建新对象(calling.new)并将外键传递给该对象是相同的。这些命令都是等效的:
Firm.first.clients.build
Firm.first.clients.new
Client.new(:firm_id => Firm.first.id)
我相信.build存在的原因是Firm.first.clients.new可能被解释为您正在创建一个新的has\u many relationship对象,而不是一个实际的客户,因此调用.build是一种澄清这一点的方法。您稍微误读了文档
some firm.client.new
正在从clients集合中创建一个新的client
对象,因此它可以自动将firm\u id
设置为some firm.id
,而文档正在调用client.new
,它根本不知道任何公司的id,因此需要将firm\u id
传递给它
some firm.clients.new
和some firm.clients.build
之间的唯一区别似乎是build
还将新创建的客户端添加到clients
集合中:
henrym:~/testapp$ rails c
Loading development environment (Rails 3.0.4)
r:001 > (some_firm = Firm.new).save # Create and save a new Firm
#=> true
r:002 > some_firm.clients # No clients yet
#=> []
r:003 > some_firm.clients.new # Create a new client
#=> #<Client id: nil, firm_id: 1, created_at: nil, updated_at: nil>
r:004 > some_firm.clients # Still no clients
#=> []
r:005 > some_firm.clients.build # Create a new client with build
#=> #<Client id: nil, firm_id: 1, created_at: nil, updated_at: nil>
r:006 > some_firm.clients # New client is added to clients
#=> [#<Client id: nil, firm_id: 1, created_at: nil, updated_at: nil>]
r:007 > some_firm.save
#=> true
r:008 > some_firm.clients # Saving firm also saves the attached client
#=> [#<Client id: 1, firm_id: 1, created_at: "2011-02-11 00:18:47",
updated_at: "2011-02-11 00:18:47">]
henrym:~/testapp$rails c
加载开发环境(Rails 3.0.4)
r:001>(某些公司=公司。新)。保存创建并保存新公司
#=>正确
r:002>一些公司客户#还没有客户
#=> []
r:003>some_firm.clients.new#创建一个新客户
#=> #
r:004>一些公司客户#仍然没有客户
#=> []
r:005>some_firm.clients.build#使用build创建新客户
#=> #
r:006>一些公司客户#新客户被添加到客户中
#=> [#]
r:007>一些公司
#=>正确
r:008>一些_firm.clients#保存公司也保存附加的客户
#=> [#]
如果您是通过关联创建对象,build
应优先于new
,因为build使您的内存对象保持一致状态,某些公司(在本例中)甚至在将任何对象保存到数据库之前都保持一致状态。只是new
的别名:
alias build new
可以找到完整的代码:build
vsnew
:
alias build new
大多数新建和生成都是相同的,但生成将对象存储在内存中
例如:
对于新的:
Client.new(:firm_id=>Firm.first.id)
对于构建:
Firm.first.clients.build
在这里,客户机存储在内存中,当保存公司时,也会保存相关记录。Model.new
Tag.new post\u id:1
将实例化设置了post\u id
的标记
@模型
@post.tags.build
执行相同的操作,并且即使在保存之前,实例化的标记仍将位于@post.tags
中
这意味着@post.save
将同时保存@post和新构建的标记(假设设置了:inverse_of)。这很好,因为Rails将在保存之前验证这两个对象,如果其中任何一个未通过验证,则不会保存任何一个对象
模型。新与模型。构建
@post.tags.build
和@post.tags.new
是等效的(至少从Rails 3.2开始)。使用some-firm.client.new
还将客户端添加到some-firm.clients
,并在some-firm
上调用save
导致验证错误,表明客户端
无效。如果new
和build
都将新客户添加到某公司的客户集合中,那么build
会做什么new
不会做什么?对不起,我说的太多了,这里+1我以3.0.4的成绩收到了你的成绩。我希望有3.0.3版本的人能确认我没有疯。@henrym 3.2.6中的clients.new和clients.build类似,它们都将新对象添加到集合中。我想为那些在谷歌搜索时遇到这个问题的人添加一条评论。在Rails 3.2.3中,这两个问题看起来没有什么区别。对于Rails>3.2.13,这个答案是不正确的,因为“build”只是“new”的别名。见下文@HatemMahmoud的答案。因此它们是等价的。看起来确实如此。非常感谢。这是不对的。前两个在Rails的更高版本中是等效的(看起来在发布时它们不是)。但是,最后一个在该公司有很大的不同。首先,客户不会包含新客户。alias build new
从rails 3.2.13开始,这只适用于某些关联/关系。例如,单一关联对build
和build#{association}
有完全不同的定义。请参阅和。对于Rails 4
,这仍然是正确的吗?是错误报告。。。这表明,如果您使用新的,如restaurant.customers.new,作为一种获得与餐厅关联的新客户的方法,而无需将其附加到restaurant.customers,则使用作用域。。。例如restaurant.customers.scoped.new这个怎么样一些_firm.clients.new和一些_firm.clients.build之间的唯一区别似乎是build还将新创建的客户添加到客户中