在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的。 我正在控制台上盯着结果!
我错过了什么吗? 文档有点过时(不太可能)? build
和new
什么区别?
你误解了文档。 some_firm.client.new
正在从客户端集合中创build一个新的Client
对象,因此它可以自动将firm_id
设置为some_firm.id
,而文档则调用Client.new
,它根本不知道任何公司的ID,所以它需要把firm_id
传递给它。
some_firm.clients.new
和some_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立商店对象,新的不会。
它们都将对象存储在内存中: