2016-08-25 7 views
2

私は次のデータベース構造を持つeコマースサイトだ想像してネストされた団体を通じて合計フィルター:高度なActiveRecordのクエリ:

  • 注文にhas_manyののOrderItems製品belongs_toの
  • のOrderItem
  • ORDER_ITEMS表は、列、数量を持って
  • 商品表には の価格、価格があります。

オーダーを合計価格でフィルタリングできるオーダーモデルで範囲を作成したいと考えています。それは注文の合計です(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) 

私のクエリで何が問題になっているかについてのガイダンスはありますか?

答えて

0
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) P.S.のようにこれを使用することができます - total_amountにアクセスすることもできます。これは、このクエリによって返されたインスタンスのメソッドとして呼び出します。

私はそれがその方法は+あなたがする必要はありませんんものに人のための、より単純であるため、代わりにgtltの兆候を使用する方が良いと思います

(そのアイテムの総コストを返す)Order.total_cost(:>, 10).first.total_costのように不要なマッピングを行う

最も洗練されたソリューションではないかもしれませんが、機能します。