2013-11-04 29 views
25

新的軌道和我正在跟蹤使用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 ...

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

回答

48

你誤會了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

1

我打算繼續說你完全正確。這兩種方法都可以工作,並且可以執行相同的操作,但只使用:product_id的版本更加高效,並且需要少量的數據庫查詢。也就是說,如果您稍後在代碼中需要product變量,或者特定的訂單項稍後調用product.{something},那麼它可能是有意義的,因此它不必在此時通過id獲取它。

但是,我個人寧願只設置:product_id,我看不出有任何理由首先找到對象。