2009-09-03 18 views
38

क्या किसी को यह निर्धारित करने का कोई तरीका पता है कि रेल एसोसिएशन उत्सुक हो गया है या नहीं?रेलवे एसोसिएशन उत्सुक लोड होने पर कैसे निर्धारित किया जाए?

मेरी स्थिति: मेरे पास एक परिणाम सेट है जहां कभी-कभी संघों में से एक उत्सुक लोड होता है, और कभी-कभी यह नहीं होता है। यदि यह उत्सुक नहीं है, तो मैं ActiveRecord के खोज का उपयोग करके एसोसिएशन देखना चाहता हूं। यदि यह उत्सुक भारित है, तो मैं पहचान का उपयोग करना चाहता हूं।

उदाहरण के लिए, कहें कि मेरे आइटम मॉडल में शिपिंग_इनफ़ो ऑब्जेक्ट्स की "has_many" सरणी है। तब:

तो आइटम उत्सुक भरी हुई है, सबसे कुशल लोड है:

item.shipping_infos.detect { |si| si.region == "United States" } 

तो आइटम उत्सुक भरी हुई, सबसे कुशल लोड कर रहा है नहीं है:

item.shipping_infos.where(region: "United States").first 

लेकिन जब तक मैं क्या यह पता उत्सुक भारित है, मुझे नहीं पता कि रिकॉर्ड को कुशलतापूर्वक प्राप्त करने के लिए कौन सा कोड कॉल करना है। अगर मैं पहली विधि का उपयोग करता हूं जब यह उत्सुक नहीं होता है, तो मुझे आवश्यकतानुसार अधिक डीबी रिकॉर्ड देखना होगा। और अगर मैं दूसरी विधि का उपयोग करता हूं, जब यह उत्सुक था, तो मेरी उत्सुक भारित वस्तुओं को अनदेखा कर दिया जाता है।

उत्तर

41

item.shipping_infos.loaded? आपको बताएगा।

मैं, कहना होगा, हालांकि: कोड है कि loaded? परीक्षण #detect और #find के बीच तय करने लिखने से पहले इस मार्ग पागलपन की ओर जाता है ..., यकीन है कि यह उदाहरण वास्तव में मामलों, बाकी सब है कि क्या हो रहा है के सापेक्ष हैं।

यदि यह आपके ऐप की सबसे धीमी चीज नहीं है, तो अतिरिक्त कोड पथ जोड़ना अनावश्यक जटिलता जोड़ता है। सिर्फ इसलिए कि आप थोड़ा डेटाबेस प्रयास बर्बाद कर सकते हैं इसका मतलब यह नहीं है कि आपको इसे ठीक करने की आवश्यकता है - यह शायद किसी भी मापनीय तरीके से कोई फर्क नहीं पड़ता।

+0

धन्यवाद ब्रायन। मैं समझता हूं कि आप कहां से आ रहे हैं। यह विशेष कोड हमारे पूरे ऐप में सबसे अधिक बार आंशिक आंशिक रूप से होता है, हालांकि, माइक्रोसॉन्ड से भी शेविंग करना एक मापनीय अंतर बनाता है। मैं #loaded दे दूंगा? एक कोशिश। – wbharding

+9

यह केवल has_many संगठनों के लिए काम करेगा! इस कॉल के संबंधित_इस मामले में वास्तव में अन्य ऑब्जेक्ट लोड होगा (इसलिए यह हमेशा सत्य होगा) – reto

2

Bullet gem. पर एक नज़र डालें। यह आपको बताएगा कि आपको उत्सुक लोडिंग का उपयोग क्यों करना चाहिए और नहीं करना चाहिए।

+0

बुलेट वास्तव में उपयोगी साबित हुआ है, भले ही मैंने अभी तक बहुत कम डीबी अनुकूलन किया है। कम से कम यह कंसोल आउटपुट में कुछ अनावश्यक लाइनों से छुटकारा पाता है। ;) – lime

+0

बुलेट प्लगइन लिंक मर चुका है। –

3

आप यह पता लगा सकते हैं कि एक ही एसोसिएशन loaded_ foo के साथ लोड किया गया है या नहीं? उदाहरण के लिए, यदि shipping_info एक related_to एसोसिएशन था, तो item.loaded_shipping_info? जब यह उत्सुकता से भरा हुआ हो तो सच हो जाएगा। विचित्र रूप से, ऐसा लगता है कि यह लोड नहीं किया गया है (रेलवे 2.3.10 में वैसे भी) शून्य (बदले के बजाय) वापस लौटता है।

+3

इसे रेल 3.1 में हटा दिया गया है: https://github.com/rails/rails/issues/472 – Forrest

2

इस समस्या का समाधान foo.association(:bla).loaded? होना चाहिए, लेकिन इसे गलत तरीके से काम करता है - यह जाँच करता है और अंक संघ के रूप में गंदा:

class Foo; has_one :bla, :autosave => true end 
foo.association(:bla).loaded? #=> false 
foo.save # saves foo and fires select * from bla 

तो मैं ActiveRecord करने के लिए विस्तार निम्नलिखित जोड़ दिया है:

module ActiveRecord 
    class Base 
    def association_loaded?(name) 
     association_instance_get(name).present? 
    end 
    end 
end 

और अब:

class Foo; has_one :bla, :autosave => true end 
foo.association_loaded?(:bla) #=> false 
foo.save # saves foo 
+0

आपको यह जांचना चाहिए कि यह अभी भी एक समस्या है और उचित रेल संस्करणों के दायरे के उत्तर को अपडेट करें। मैं पुन: पेश करने में असमर्थ था। –

+0

अभी भी रेल 4.2.6 के रूप में एक समस्या है। यकीन नहीं है कि रेल 5 में यह है या नहीं। – Omnilord

+0

इसे गंदा के रूप में चिह्नित करने का क्या परिणाम है? बस एक अतिरिक्त चयन कथन? या इसके लिए और अधिक नुकसान है? – lulalala

19

मैं item.association_ का उपयोग करने का सुझाव दूंगा cache.keys जो उत्सुक भारित संघों की एक सूची प्रदान करेगा। तो आप item.association_cache.keys.include?: name_of_association

+1

बिल्कुल सही समाधान। डबोगर्ट आप राजा हैं :) – Benj

+0

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

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