在Rails中构buildvs new 3

在Rails 3 文档中 ,关联的build方法被描述为与new方法相同,但是具有外键的自动分配。 直接从文档:

 Firm#clients.build (similar to Client.new("firm_id" => id)) 

我读过类似的其他地方。

但是,当我使用new (例如some_firm.clients.new没有任何参数),新客户的firm_id关联自动创build的。 我正在控制台上盯着结果!

我错过了什么吗? 文档有点过时(不太可能)? buildnew什么区别?

你误解了文档。 some_firm.client.new正在从客户端集合中创build一个新的Client对象,因此它可以自动将firm_id设置为some_firm.id ,而文档则调用Client.new ,它根本不知道任何公司的ID,所以它需要把firm_id传递给它。

some_firm.clients.newsome_firm.clients.build之间的唯一区别似乎是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">] 

如果通过关联创build一个对象, build应该优先于new构build, some_firm即使在将任何对象保存到数据库之前, build也会保持内存对象some_firm (在本例中)处于一致状态。

build只是一个new的别名:

 alias build new 

完整的代码可以find: https : //github.com/rails/rails/blob/master/activerecord/lib/active_record/relation.rb

你是正确的,构build和新function有相同的设置外键的效果,当他们被调用通过一个关联。 我相信这样写文档的原因是为了阐明一个新的Client对象被实例化,而不是一个新的活动logging关系。 这与在类中调用.new会在Ruby中具有相同的效果。 也就是说,文档阐明了调用build立关联是相同的是创build一个新的对象(调用.new)并将外键传递给该对象。 这些命令都是等价的:

 Firm.first.clients.build Firm.first.clients.new Client.new(:firm_id => Firm.first.id) 

我相信.build存在的原因是,Firm.first.clients.new可能被解释为意味着你正在创build一个新的has_many关系对象,而不是一个实际的客户端,所以调用.build是澄清这一点的一种方式。

构buildvs新:

大部分新build构build都是一样的,但是在内存中构build存储对象,

例如。

对于新的:

 Client.new(:firm_id=>Firm.first.id) 

构build:

 Firm.first.clients.build 

这里客户端存储在内存中,当保存牢固时,关联的logging也被保存。

Model.new

Tag.new post_id: 1将实例化具有其post_id集的标签。

@ model.models.new

@post.tags.build也是一样的即使在保存之前,实例化的标签也会在@post.tags

这意味着@post.save将保存@post和新build标签(假设:inverse_of被设置)。 这很好,因为Rails在保存之前会validation这两个对象,如果其中任何一个validation失败,都不会被保存。

models.new vs models.build

@post.tags.build@post.tags.new是等价的(至less从Rails 3.2开始)。

我不确定关于老版本的rails ruby​​,但是从rails5.0.1开始,build只是新的别名:

 alias build new 

完整的代码可以在这里find。

下面是一个例子,说明没有任何不同,像在内存中build立商店对象,新的不会。

它们都将对象存储在内存中:

在这里输入图像描述