Ruby-on-rails 在 Rails 3 中构建与新建
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4954313/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Build vs new in Rails 3
提问by ClosureCowboy
In the Rails 3 docs, the buildmethod for associations is described as being the same as the newmethod, but with the automatic assignment of the foreign key. Straight from the docs:
在 Rails 3文档中,build关联方法被描述为与new方法相同,但具有外键的自动分配。直接来自文档:
Firm#clients.build (similar to Client.new("firm_id" => id))
I've read similar elsewhere.
我在别处读过类似的。
However, when I use new(e.g. some_firm.clients.newwithout any parameters), the new client's firm_idassociation isautomatically created. I'm staring at the results right now in the console!
但是,当我使用new(例如some_firm.clients.new不带任何参数)时,会自动创建新客户端的firm_id关联。我现在正在控制台中盯着结果!
Am I missing something? Are the docs a bit out of date (unlikely)? What's the difference between buildand new?
我错过了什么吗?文档是否有点过时(不太可能)?build和 和有new什么区别?
回答by henrym
You're misreading the docs slightly. some_firm.client.newis creating a new Clientobject from the clients collection, and so it can automatically set the firm_idto some_firm.id, whereas the docs are calling Client.newwhich has no knowledge of any Firm's id at all, so it needs the firm_idpassed to it.
你稍微误读了文档。some_firm.client.new正在Client从客户端集合创建一个新对象,因此它可以自动将 设置firm_id为some_firm.id,而文档正在调用Client.new它根本不知道任何公司的 id,因此它需要firm_id传递给它。
The only difference between some_firm.clients.newand some_firm.clients.buildseems to be that buildalso adds the newly-created client to the clientscollection:
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">]
If you're creating an object through an association, buildshould be preferred over newas build keeps your in-memory object, some_firm(in this case) in a consistent state even before any objects have been saved to the database.
如果您通过关联创建对象,则build应该优先于newbuild 使您的内存对象some_firm(在这种情况下)保持一致状态,甚至在任何对象已保存到数据库之前。
回答by Hatem Mahmoud
buildis just an alias for new:
build只是一个别名new:
alias build new
Full code can be found: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation.rb#L74
完整代码可见:https: //github.com/rails/rails/blob/master/activerecord/lib/active_record/relation.rb#L74
回答by Pan Thomakos
You are correct, the build and new functions have the same effect of setting the foreign key, when they are called through an association. I believe the reason the documentation is written like this is to clarify that a new Client object is being instantiated, as opposed to a new active record relationship. This is the same effect that calling .new on a class would have in Ruby. That is to say that the documentation is clarifying that calling build on an association is the same is creating a new object (calling .new) and passing the foreign keys to that object. These commands are all equivalent:
你是对的,当通过关联调用 build 和 new 函数时,它们具有设置外键的相同效果。我相信文档写成这样的原因是为了澄清一个新的 Client 对象正在被实例化,而不是一个新的活动记录关系。这与在 Ruby 中对类调用 .new 的效果相同。也就是说,文档澄清了在关联上调用 build 与创建新对象(调用 .new)并将外键传递给该对象是一样的。这些命令都是等价的:
Firm.first.clients.build
Firm.first.clients.new
Client.new(:firm_id => Firm.first.id)
I believe the reason .build exists is that Firm.first.clients.new might be interpreted to mean that you are creating a new has_many relationship object, rather than an actual client, so calling .build is a way of clarifying this.
我相信 .build 存在的原因是 Firm.first.clients.new 可能被解释为意味着您正在创建一个新的 has_many 关系对象,而不是一个实际的客户端,所以调用 .build 是一种澄清这一点的方式。
回答by Sarwan Kumar
buildvs new:
build对比new:
mostly new and build are same but build stores object in memory,
大多数 new 和 build 是相同的,但build 将对象存储在内存中,
eg:
例如:
for new:
对于新的:
Client.new(:firm_id=>Firm.first.id)
For build:
对于构建:
Firm.first.clients.build
Here clients are stored in memory, when save firm , associated records are also saved.
这里的客户端存储在内存中,当保存公司时,相关的记录也被保存。
回答by tybro0103
Model.new
新模型
Tag.new post_id: 1will instantiate a Tag with its post_idset.
Tag.new post_id: 1将用它的post_id集合实例化一个标签。
@model.models.new
@model.models.new
@post.tags.builddoes the same ANDthe instantiated Tag will be in @post.tagseven before it's saved.
@post.tags.build做同样的和实例化的标签将成为@post.tags它的保存,甚至之前。
This means @post.savewill save both the @post and the newly built tag (assuming :inverse_of is set). This is great because Rails will validate both objects before saving, and neither will be saved if either one of them fails validation.
这意味着@post.save将同时保存@post 和新构建的标签(假设 :inverse_of 已设置)。这很好,因为 Rails 会在保存之前验证两个对象,如果其中一个未通过验证,则两个对象都不会被保存。
models.new vs models.build
models.new 与 models.build
@post.tags.buildand @post.tags.neware equivalent (at least since Rails 3.2).
@post.tags.build并且@post.tags.new是等效的(至少从 Rails 3.2 开始)。

