2012-01-25 16 views
14

रेल 3 एपीआई के आधार पर, एक दायरे और कक्षा विधि के बीच का अंतर लगभग मौजूद नहीं है।रेल में स्कॉप बनाम क्लास विधि 3

class Shipment < ActiveRecord::Base 
    def self.unshipped 
    where(:shipped => false) 
    end 
end 

रूप

scope :unshipped, where(:shipped => false) 

हालांकि एक ही है, मैं खोजने रहा है कि मैं कभी कभी उनका इस्तेमाल अलग-अलग परिणाम हो रही है।

जबकि वे दोनों एक ही, सही SQL क्वेरी उत्पन्न करते हैं, तो कॉल हमेशा कॉल किए जाने पर सही मान वापस नहीं आती है। ऐसा लगता है कि यह समस्या केवल तब होती है जब विधि में एक अलग शिपमेंट पर यद्यपि इसे दो बार कहा जाता है। दूसरी बार जब इसे कॉल किया जाता है, तो स्कोप का उपयोग करते समय यह वही काम करता है जो पहली बार हुआ था। जबकि अगर मैं कक्षा विधि का उपयोग करता हूं तो यह सही तरीके से काम करता है।

क्या स्कोप का उपयोग करते समय कुछ प्रकार की क्वेरी कैशिंग होती है?

संपादित करें:

order.line_items.unshipped 

ऊपर लाइन कैसे गुंजाइश बुलाया जा रहा है। ऑर्डर में कई line_items हैं।

जेनर_मल्टीपी_शिपमेंट विधि को दो बार बुलाया जा रहा है क्योंकि परीक्षण एक आदेश बनाता है और यह देखने के लिए शिपमेंट उत्पन्न करता है कि कितने हैं। इसके बाद यह आदेश में बदलाव करता है और शिपमेंट को पुन: उत्पन्न करता है। हालांकि, group_by_ship_date उसी परिणाम को देता है जो उसने आदेश के पहले पुनरावृत्ति से किया था।

def generate_multiple_shipments(order) 
    line_items_by_date = group_by_ship_date(order.line_items.unshipped) 

    line_items_by_date.keys.sort.map do |date| 
    shipment = clone_from_order(order) 
    shipment.ship_date = date 
    line_items_by_date[date].each { |line_item| shipment.line_items << line_item } 
    shipment 
    end 
end 

def group_by_ship_date(line_items)  
    hash = {} 
    line_items.each do |line_item| 
    hash[line_item.ship_date] ||= [] 
    hash[line_item.ship_date] << line_item 
    end 
    hash 
end 
+2

आपको एक उदाहरण (कोड का स्निपेट) जहां आपको लगता है कि जब दो बार बुलाया क्वेरी कैश की गई हो जाता है प्रदान करें कर सकते हैं। –

+0

मैंने मूल पोस्ट में और जानकारी जोड़ दी है। – blim8183

+0

रेल लॉग का निरीक्षण करने से आपको पता चलेगा कि परिणाम कैश किया जा रहा है या नहीं। – Sasha

उत्तर

1

मुझे लगता है कि आपका आमंत्रण गलत है। तुम्हें पता है, गुंजाइश निष्पादित करने के लिए क्वेरी विधि तथाकथित जोड़ना चाहिए जैसे all, first, last, यानी .:

order.line_items.unshipped.all 

मैं कुछ विसंगतियां, विशेष रूप से rspec में, तो वह पूछताछ विधि जोड़कर परहेज कर रहे हैं मनाया गया है।

आपने अपना टेस्ट कोड पोस्ट नहीं किया है, इसलिए सटीक कहना मुश्किल है, लेकिन मेरा अपवाद यह है कि आप संबंधित रिकॉर्ड संशोधित करने के बाद, आपको एक रीलोड को मजबूर करना होगा, क्योंकि क्वेरी कैश हमेशा पर्याप्त स्मार्ट नहीं है एक परिवर्तन का पता लगाएं। संघ के true गुजर करके, आप फिर से लोड करने संघ मजबूर कर सकते हैं और फिर से चलाने के लिए क्वेरी:

order.line_items(true).unshipped.all 
+0

एसोसिएशन को पुनः लोड करने के लिए मजबूर करना ऐसा लगता है कि चाल चल रही है। मैं अभी भी पूरी तरह से स्पष्ट नहीं हूं कि क्वेरी कैश कैसे निर्धारित करता है कि कोई बदलाव आया है लेकिन कम से कम यह अब काम कर रहा है। धन्यवाद! – blim8183

+0

@ blim8183 मुझे इसका उत्तर नहीं पता है, लेकिन मुझे संदेह है कि यह एक डिज़ाइन व्यापार-बंद हो सकता है। खुशी है कि आपके लिए रीलोड काम करता है। –

1

यह मानते हुए कि आप रेल 3.1 संदर्भित कर रहे हैं, एक गुंजाइश डिफ़ॉल्ट गुंजाइश है कि अपने मॉडल पर परिभाषित किया जा सकता है, जबकि एक वर्ग विधि नहीं होगा से प्रभावित हो सकते हैं।

संबंधित मुद्दे