试图理解:has_many
在敏捷Web开发第4版中引入的效果
为购物车设置了以下关系
class Cart < ActiveRecord::Base
has_many :line_items, :dependent => :destroy
end
这与相关的LineItem
类
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方法的效果。
“谢谢。
答案 0 :(得分:2)
将我的回答视为 Chris Kimpton的答案的一个非常重要的评论。
首先,您应该阅读API documentation,其中很好地解释了关联。
简而言之,当您在类的代码中调用方法has_many
时(请记住,在Ruby中,每一行都是执行的代码,因此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对象的集合对象(这是一个简化示例)。
该集合对象的工作方式与数组类似,但它也会响应更多方法(如find
或build
),帮助您管理Cart对象之间的关系和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
添加到每个语句中。
答案 1 :(得分: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
答案 2 :(得分:1)
我假设代码行示例是Cart类的方法吗?
ActiveRecord / has_many调用的一个“功能”是将此伪方法添加到您的类中。
因此Cart类获得了一个line_items方法来访问它们。
line_items.where调用是在相关的line_items内搜索 - 而不是所有LineItems,这是您的调用。它似乎在寻找与特定产品相关的line_item - 我想知道product_id var来自哪里 - 方法参数?
另一方面,LineItem上的belongs_to调用添加了一个“cart”方法来访问它所在的Cart。
希望这有帮助, 克里斯