如何在Rails 5.2中通过has_many预载has_one?

时间:2018-11-06 17:18:59

标签: ruby-on-rails activerecord ruby-on-rails-5

我正在寻找一种通过has_many预先加载has_one关系的方法。我有4种相关模型:

class Order
  has_many :line_items
  has_many :products, through: :line_items

  has_one :review
  has_many :review_items, through: :review
end

class Review
  belongs_to :order
  has_many :review_items
  has_many :products, through: :review_items
end

class ReviewItem
  belongs_to :review
  belongs_to :product

  has_one :order, through: :review
end

class LineItem
  belongs_to :order
  belongs_to :product

  has_one :review, through: :order

  # HERE IS RELATION IN QUESTION
  has_one :review_item, ->(product) { where(product_id: line_item. product_id, review: line_item.review) }, foreign_key: "product_id", primary_key: "product_id"

end

问题是如何通过review_item来将LineItem预先加载到line_item上,以便我可以做类似Order.include(line_items: [:review_item]).where(user: user)

的操作

当前,我得到了错误

  

关联范围review_item依赖于实例(范围块带有一个参数)。不支持预加载实例相关的范围。)

因此,我正在寻找一种具有has_one关系的方法,但不必在查询实例时传递实例。

查询应该很简单,它与

# in LineItem
  def review_item
    review.find_by(meal_id: self.meal_id)
  end

但是显然我不能预加载它。

我觉得必须有一种方法可以编写不包含has_one实例的LineItem关系,但是我一直在努力寻找它。

1 个答案:

答案 0 :(得分:0)

您的关系必须接受争论,因为您在LineItemReviewItem之间没有直接关系。

实际上,在问题域中,客户通常不是在审核Product,而是在订购并交付给他们的实际产品实例(= {LineItem),因此具有以下逻辑是合乎逻辑的:< / p>

class ReviewItem
  belongs_to :review
  belongs_to :line_item
  has_one :product, through: :line_item
  ...
end