我希望让所有客户及其产品属于“饮料”类别。
Here are my relations:
Customer has_many orders
Order has_many products through order_details
Product has_many Orders through order_details
Product belongs to Category
我试过了,但它并没有给所有客户。它仅向订购Beverages的客户提供。
Customer.includes(orders: {products: :category}).where(categories: { category_name: "Beverages"})
注意:我不想过滤客户记录。我需要在产品上应用过滤器,因为在这种情况下加载所有记录都是无用的。
答案 0 :(得分:1)
Active Record没有API来执行此操作。
如果您只需要几个已知类别,可以通过添加自定义关联来实现:
class Customer ..
has_many :beverage_orders, -> { includes(products: :categories).where(categories: { category_name: "Beverages" }) }, class_name: "Order"
(然后Customer.includes(:beverage_orders)
)
如果您需要支持任意类别,您的选项会变得更糟......如果客户数量不足,我会考虑跳过包含并接受N + 1查询。
否则,我建议的下一个最不好的选择是自己进行查询:
customers = Customer.all # or whatever
beverage_orders = Order.includes(products: :categories).
where(categories: { category_name: "Beverages" }).
where(customer_id: customers).
group_by(&:customer_id)
customers.each do |customer|
puts "#{customer.name} ordered #{beverage_orders[customer.id].size} beverages"
# i.e., use `beverage_orders[customer.id]` instead of `customer.orders`
end
答案 1 :(得分:-1)
如果您需要过滤记录,为何使用左连接? 尝试
Customer.joins(:orders).where(order: { product_id: Category.find_by(name: 'Beverages').products.pluck(:id) })
更新:
由于where
子句会过滤基本记录,因此它应过滤您需要自定义Customer
的{{1}}模型,以选择合适的产品,而不是过滤客户。
joins