[英]Advanced ActiveRecord Query: Filter Sum through Nested Associations
想象一下,我是一個具有以下數據庫結構的電子商務站點:
我想在我的訂單模型中創建一個范圍,該范圍能夠按訂單的總價過濾。 那就是訂單的總和(order_item數量* order_item的產品價格)。
有可能的使用:
#Get orders that have a total cost greater than 10
Order.filter_cost('gt', 10)
到目前為止,這是我形成的,但似乎並不完全有效。 我以為我不應該分組,但是如果我不使用分組會出錯。 在以下范圍內,我得到了響應,但是返回的集合不准確。
scope :filter_cost, (lambda do |*args|
if args[0] && %w(gt lt et).include?(args[0]) && args[1]
operator_map = { 'gt' => '>', 'lt' => '<', 'et' => '=' }
joins(order_items: :product).group('orders.id').group('order_items.id').group('products.id').having("SUM(products.price * order_items.quantity) #{operator_map[args[0]]} ?", args[1].to_f)
end
end)
我可以獲取有關查詢問題的一些指導嗎?
def self.total_cost(direction, amount)
select(orders.*, SUM(products.price * order_items.quantity) AS total_price).
joins(order_items: :product).
where(SUM(products.price * order_items.quantity) #{direction} #{amount})
end
現在您可以像Order.total_cost(:>, 10)
PS這樣使用它-您甚至可以通過在此查詢返回的實例上作為方法調用total_amount
來訪問total_amount
。
類似於Order.total_cost(:>, 10).first.total_cost
(返回該商品的總費用)
我認為使用符號代替gt
和lt
會更好,因為任何人都可以更直接地知道該方法的作用+您不必進行不必要的映射。
可能不是最優雅的解決方案,但它可以工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.