2011-09-08 17 views
3

試圖瞭解的:has_many及其在的Rails:的has_many解釋

下已經建立了車

class Cart < ActiveRecord::Base 
    has_many :line_items, :dependent => :destroy 
end 

此致意相關LineItem的敏捷Web開發的書第4版推出的影響類

class LineItem < ActiveRecord::Base 
    belongs_to :product 
    belongs_to :cart 
end 

一切都很好,我完全理解關係建模,只是試圖接受臨屋區這只是'工作'。但是,在代碼中,作者不是使用LineItem.find方法在基礎表上執行搜索,而是使用line_items對象,例如,

current_item = line_items.where(:product_id => product_id).first 

是否有人可以解釋這一點,最終我想,什麼:has_many方法調用的效果其實是什麼?什麼是line_items對象,它來自哪裏?我想同樣的問題將適用於其他關係Rails方法的效果。

謝謝。'

回答

2

考慮我的回答只是作爲一個非常大的評論Chris Kimpton的回答。

首先,您應該閱讀API documentation,其中的關聯很好地解釋。

總之,當調用方法has_many在類的代碼(記住,在紅寶石每一行是一個執行的代碼,所以has_many :something僅僅是一些現有的方法的調用)則該方法定義了另一個兩個名稱與您傳遞的參數相同的方法。

在這種情況下,這將是符號:line_items,所以has_many方法使東西大致相當於:def line_items(force_reload = false)def line_items=(objects)

新創建的方法line_items返回由WHERE cart_id = #{self.id}(這是一個簡化示例)篩選的所有LineItem對象的集合對象。

該集合對象就像一個數組,但它也迴應了一些更多的方法(如findbuild幫助您管理的車對象和LineItem的之間的關係。

因此,該行:

line_items.where(:product_id => some_id).first 

是等價的:

LineItem.where(:cart_id => self.id).where(:product_id => some_id).first 

使用第一種方法(在line_items集合)你不需要記住補充說:cart_id => self.id到每一個陳述。

+2

啊,這解釋說,它沒有得到任何文檔。真的很感激你解釋的時間 – Paul

1

如果代碼與您在此處編寫的代碼完全相同,則該代碼中必須已經設置了該line_items對象。

的關係的has_many將增加一個輔助方法給相關元素的列表,以便它可以做這樣的事情:

cart = Cart.find(1) 
line_items = cart.line_items 

cart.line_items將返回line_items數組,其中line_item.cart_id = cart.id

1

我認爲代碼示例行是在Cart類的方法中?

ActiveRecord/has_many調用的一個「特性」是將此僞方法添加到您的類中。

所以Cart類獲得line_items方法來訪問它們。

line_items.where調用在相關的line_items中搜索 - 不是所有LineItems,這是您的調用將執行的操作。它似乎在尋找與特定產品相關的line_item - 我想知道product_id var來自哪裏 - 方法參數?

在另一邊,belongs_to的上LineItem的調用增加了一個「購物車」的方法來訪問的車它是英寸

希望這有助於 克里斯

+1

而[has_many的API文檔](http://edgeapi.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many)可能值得一讀。它向您展示了更多可以調用該'line_items'對象的方法。 – Arsen7

+1

Chris,非常感謝你的幫助,line_items對象是從$ rails生成腳手架line_item product_id創建的:integer_cart_id:integer,它也創建了LineItem基類。謝謝你的幫助,保羅。 – Paul