2009-04-25 9 views
5

オンラインストアでは、注文が「承認済み」の状態で出荷される準備ができています。今私はこれをやっている:has_manyオブジェクトが関連付けられていないオブジェクトをすべて検索します

class Order < ActiveRecord::Base 
    has_many :shipments, :dependent => :destroy 

    def self.ready_to_ship 
     unshipped_orders = Array.new 
     Order.all(:conditions => 'state = "authorized"', :include => :shipments).each do |o| 
      unshipped_orders << o if o.shipments.empty? 
     end 
     unshipped_orders 
    end 
end 

良い方法はありますか?

答えて

8

あなたはすることもできます通常の検索の構文を使用して関連の問い合わせ:使用

Order.find(:all, :include => "shipments", :conditions => ["orders.state = ? AND shipments.id IS NULL", "authorized"]) 
+0

これは動作しません。これはhas_many関連であるため、外来キーは出荷テーブルに格納されます。 –

+0

そのため、私たちはNULL識別子 –

+0

に参加しました。私の悪い(私はSQLを吸います)。とにかく、これは動作しますが、 "状態"を "状態"(特定の場合)に置き換え、 "and"を "shipments.id"の前に追加する必要があります。これらの変更を行うと、これを答えにします。 –

1

1つのオプションは、注文にshipment_countを設定することです。注文すると、自動的に出荷される出荷数で更新されます。次に、あなただけの

Order.all(:conditions => [:state => "authorized", :shipment_count => 0]) 

また、あなたには、いくつかのSQLを持つ手が汚れて取得することができます。

Order.find_by_sql("SELECT * FROM 
    (SELECT orders.*, count(shipments) AS shipment_count FROM orders 
    LEFT JOIN shipments ON orders.id = shipments.order_id 
    WHERE orders.status = 'authorized' GROUP BY orders.id) 
    AS order WHERE shipment_count = 0") 

テスト前にそれを使用することを、SQLは正確に私の鞄ではありませんが、私はそれが近いと思うよう右に。私はそれがMySQLである私の生産DB上のオブジェクトの同様の配置のために働くようにしました。

orders.statusにインデックスがない場合は、強くお勧めします。

サブクエリは、許可ステータスのすべての注文のすべての注文数を把握します。出荷数がゼロに等しいものだけをリストする外部クエリフィルタ。

あなたがそれを行うことができ、別の方法が少し反し、おそらくあります:許可されており、出荷テーブルにエントリを持っていない

"SELECT DISTINCT orders.* FROM orders 
    LEFT JOIN shipments ON orders.id = shipments.order_id 
    WHERE orders.status = 'authorized' AND shipments.id IS NULL" 

グラブすべての注文は;)

+0

あなたの構文は偽です。conditions => {:state => "authorized"、:shipment_count => 0} ...つまり、配列ではなくハッシュを使用します。 –

12

でのRails 3をAREL

Order.includes('shipments').where(['orders.state = ?', 'authorized']).where('shipments.id IS NULL') 
関連する問題