构建方法在轨道上的红宝石

问题描述:

新的轨道和我正在跟踪使用rails 3.1的敏捷web开发中找到的Depot项目。一切都很好,直到书本使用“构建”方法时我迷路了。构建方法在轨道上的红宝石

@cart = current_cart 
product = Product.find(params[:product_id]) 
@line_item = @cart.line_items.build(product: product) 

我的谷歌搜索使我明白,.build方法仅仅是一个创建于表中的一行(与表之间的关联),更清洁的方式。但在上面的代码,我期待的代码看起来像这样的事情:

@line_item = @cart.line_items.build(product_id => params[:product_id]) 

我不明白为什么笔者不得不存储产品的整个排(产品= Product.find(PARAMS [ :product_id]))而不是仅仅得到product_id ...

有没有比我能理解的更多?

你误会了build。这只是new的别名,没什么特别的。 https://github.com/rails/rails/blob/959fb8ea651fa6638aaa7caced20d921ca2ea5c1/activerecord/lib/active_record/relation.rb#L84

build不会“创建”,在数据库中的记录,只是在内存中创建一个新的对象,这样的观点可以利用这个对象和显示的东西,尤其是对于一种形式。

对于你的第二个问题,是的,你用id编写的方式也可以。但更好的方法是不相信参数。相反,首先在db中查找来验证它。

+0

我喜欢你的答案,虽然nzifnab有相同的答案,你的提示使我成为一个更好的开发者:) – Finks

+0

通过协会做不需要构建?与当前版本完全不同 – ahnbizcad

+0

澄清 - 在当前的Rails中,ActiveRecord :: Relation#build'被别名为'ActiveRecord :: Relation#new',但'ActiveRecord :: Associations :: CollectionProxy#new'被别名为'ActiveRecord: :关联:: CollectionProxy#build'(相反的方向)。通过关联,'build' /'new'将创建新记录,并将记录ID适当关联。因此,Relation#build和Relation#new与CollectionProxy#build和CollectionProxy#new的实现略有不同。但是,由于它们在两个类中都是别名,因此使用'build'或'new'并不重要。 – sealocal

我打算继续说你完全正确。这两种方法都可以工作,并且可以执行相同的操作,但只使用:product_id的版本更加高效,并且需要少量的数据库查询。也就是说,如果您稍后在代码中需要product变量,或者特定的订单项稍后调用product.{something},那么它可能是有意义的,因此它不必在此时通过id获取它。

但是,我个人宁愿只设置:product_id,我看不出有任何理由首先找到对象。