试图了解: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方法的效果。谢谢。'
最佳答案
将我的回答视为对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对象的集合对象(这是一个简化的示例)。
该集合对象的工作方式类似于Array,但它还会响应其他一些方法(例如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
添加到每个语句中的情况。