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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 00:23:04  来源:igfitidea点击:

Build vs new in Rails 3

ruby-on-railsruby-on-rails-3associations

提问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_idsome_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

回答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 开始)。