【问题标题】:How to preload a has_one through a has_many in Rails 5.2?如何在 Rails 5.2 中通过 has_many 预加载 has_one?
【发布时间】:2018-11-06 17:18:59
【问题描述】:

我正在寻找一种通过 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

问题是在通过line_item 获取LineItem 时如何在LineItem 上预加载review_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

但显然我无法预加载它。

我觉得必须有一种方法可以编写不采用 LineItem 实例的 has_one 关系,但我很难找到它。

【问题讨论】:

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


    【解决方案1】:

    因为LineItemReviewItem 之间没有直接关系,所以您的关系必须进行论证。

    实际上,在问题域中,客户审查的不是一般的Product,而是订购并交付给他们的实际产品实例 (=LineItem),因此具有以下逻辑是合乎逻辑的:

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

    【讨论】:

    • 是的,这就是问题:)。我想在两者之间建立直接关系,但没有实际修改数据库模式。您的建议是一个很好的建议,但在这种情况下我无法这样做(为简洁起见,我提供的示例已修改)。我觉得我应该能够建立直接关系,因为我有两个字段可以创建这种连接而无需任何技巧。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-01
    • 2011-06-05
    • 2018-04-08
    • 1970-01-01
    相关资源
    最近更新 更多