Rails:has_many解释

时间:2011-09-08 06:49:51

标签: ruby-on-rails-3 activerecord

试图理解: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方法的效果。

“谢谢。

3 个答案:

答案 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对象的集合对象(这是一个简化示例)

该集合对象的工作方式与数组类似,但它也会响应更多方法(如findbuild,帮助您管理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。

希望这有帮助, 克里斯