2009-04-25 14 views
5

मेरे ऑनलाइन स्टोर में, ऑर्डर "अधिकृत" स्थिति में शिप करने के लिए तैयार है और उसके पास पहले से कोई भी शिपमेंट नहीं है। अभी मैं यह कर रहा हूं:सभी ऑब्जेक्ट्स को कोई संबंधित है_मनी ऑब्जेक्ट्स

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

यही कारण है कि हम नल पहचानकर्ता –

+0

पर शामिल होते हैं, मेरा बुरा (मैं एसक्यूएल पर चूसता हूं)। वैसे भी, यह काम करता है, सिवाय इसके कि आपको "स्थिति" के साथ "स्थिति" को बदलना है (मेरे विशेष मामले के लिए) और "shipments.id" से पहले "और" जोड़ें। उन परिवर्तनों को करें, और मैं इसे उत्तर चिह्नित करूंगा। –

1

एक विकल्प ऑर्डर पर shipment_count डालना है, जहां इसे स्वचालित रूप से शिपमेंट की संख्या के साथ अपडेट किया जाएगा। तो फिर तुम सिर्फ

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

वैकल्पिक रूप से, आप अपने हाथों कुछ एसक्यूएल के साथ गंदे हो सकते हैं:

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") 

टेस्ट कि पहले इसे का उपयोग, के रूप में एसक्यूएल वास्तव में मेरा बैग नहीं है, लेकिन मुझे लगता है कि यह करीब है करने के लिए दाहिनी ओर। मुझे अपने उत्पादन डीबी पर वस्तुओं की समान व्यवस्था के लिए काम करने के लिए मिला, जो MySQL है।

ध्यान दें कि यदि आपके पास ऑर्डर पर कोई अनुक्रमणिका नहीं है। स्टेटस मैं दृढ़ता से सलाह देता हूं!

क्या पूछताछ करता है: सबक्वायरी सभी आदेशों के लिए सभी आदेश गणना करता है जो अधिकृत स्थिति में हैं। बाहरी क्वेरी फ़िल्टर जो केवल उन लोगों को सूचीबद्ध करते हैं जिनके पास शिपमेंट की गणना शून्य के बराबर होती है।

संभवतः एक और तरीका है कि आप यह कर सकता है, एक छोटे से counterintuitively:

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

ले लो सभी आदेशों जो अधिकृत कर रहे हैं और लदान तालिका में एक प्रविष्टि नहीं है;)

+0

आपका वाक्यविन्यास फर्जी है, होना चाहिए: शर्तें => {: state => "अधिकृत",: shipment_count => 0} ... दूसरे शब्दों में, एक हैश का उपयोग करें, एक सरणी नहीं। –

12

में रेल 3 का उपयोग AREL

Order.includes('shipments').where(['orders.state = ?', 'authorized']).where('shipments.id IS NULL') 
संबंधित मुद्दे