2015-01-06 6 views
9

मैं पैरेंट ऑब्जेक्ट के साथ एक साथ संघों पढ़ने एक instantiated ऑब्जेक्ट से एक संघ उत्सुक लोड करने के लिए कोशिश कर रहा हूँ, यानी बजाय के लिए 4 उत्सुक लोड ...रेल एक वस्तु

User.includes(:characters).first 

... यह स्थगित जब तक मैं तय यह वास्तव में आवश्यक है और इस तरह कुछ करना:

u = User.first 
# Other stuff ... 
u.eager_load(:characters) 

रेल 3 मैं इस विधि के साथ ActiveRecord बढ़ाया में:

def eager_load(*args) 
    ActiveRecord::Associations::Preloader.new(self, *args).run 
end 

और यह ठीक काम किया। 4 इस हिस्से कुछ बदल रेल और मैं करने के लिए विधि अपडेट:

def eager_load(*args) 
    ActiveRecord::Associations::Preloader.new.preload(self, *args) 
end 

दुर्भाग्य से, यह अब कुछ अजीब है। एक नज़र डालें:

2.1.2 :001 > u = User.first 
[2015-01-06 23:18:03] DEBUG ActiveRecord::Base : User Load (0.3ms) SELECT `users`.* FROM `users` ORDER BY `users`.`id` ASC LIMIT 1 
=> #<User id: 1, ...> 
2.1.2 :002 > u.eager_load :characters 
[2015-01-06 23:18:07] DEBUG ActiveRecord::Base : Character Load (0.2ms) SELECT `characters`.* FROM `characters` WHERE `characters`.`user_id` IN (1) 
[2015-01-06 23:18:07] DEBUG ActiveRecord::Base : Character Load (0.3ms) SELECT `characters`.* FROM `characters` 
[2015-01-06 23:18:07] DEBUG ActiveRecord::Base : Character Load (0.2ms) SELECT `characters`.* FROM `characters` 
=> [#<ActiveRecord::Associations::Preloader::HasMany:0x00000007c26d28 @klass=Character(id: integer, ...), @owners=[#<User id: ...], @reflection=#<ActiveRecord::Reflection::HasManyReflection:0x0000000496aa60 @name=:characters, ...(LOTS of stuff here)...] 

नोट विशेष रूप से सभी रिकॉर्डों का डबल चयन नोट करें। क्या मैं इस व्यवहार या किसी अन्य विधि को ठीक करने का कोई तरीका है जो मैं चाहता हूं?

+1

आपके उदाहरण में, आप मूल वस्तु के साथ एसोसिएशन को एक साथ क्यों नहीं पढ़ना चाहते हैं? और आप केवल 'यू .characters' क्यों कह सकते हैं - क्या यह केवल पात्रों को प्राप्त करने के मामले को पूरा करेगा जब आपको उनकी आवश्यकता होगी? – Nona

+0

यह केवल समस्या का प्रदर्शन करने के लिए था। मैं एन + 1 प्रश्नों को रोकने के लिए गहरी संरचना (उदा।'characters: {आइटम:: विशेषताएँ} ') को प्रीलोड करना चाहूंगा। –

+3

मैं उपयोग के मामले को समझ नहीं सकता जहां 'शामिल है (वर्ण: {आइटम:: विशेषताएँ}) 'पर्याप्त नहीं है? – omarvelous

उत्तर

1

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

u.eager_load(:characters); nil 

मुझे आशा है कि यह मदद, मैं इस समय इस पर काम कर रहा हूँ, तो यह मेरी केवल अवलोकन अब तक है ।

+0

अविश्वसनीय लोड हो जाएगा। हां, यह मदद करता है और अनियंत्रित प्रश्न समाप्त हो जाते हैं। और हाँ, मैंने जांच की है कि वास्तव में सर्वर लॉग में यह बिल्कुल खुश नहीं होता है। लेकिन मैं समझ नहीं पा रहा हूं कि यहां क्या होता है। * क्या * के साथ और बिना मूल्यांकन किया जाता है; nil' ...? –

+0

मेरा (शिक्षित) अनुमान है कि प्रीलोडर ऑब्जेक्ट ('.preload' को कॉल करते समय लौटाया गया) एक' ActiveRecord :: Relation' (अब से संबंध) के समान है। कंसोल में, यदि आप चरणबद्ध रूप से एक संबंध चरण बनाते हैं, तो क्वेरी हर बार निष्पादित की जाती है (केवल इसलिए कि प्रत्येक कथन कंसोल में लौटाता है), लेकिन सर्वर में आप एक रिश्ता बनाते हैं और केवल परिणामों को "अनुरोध" करते समय इसे चलाते हैं (उनके माध्यम से लूपिंग, आदि)। बस स्पष्ट होने के लिए, आपको 'की आवश्यकता नहीं है; सर्वर पर, बस कंसोल। – Leito

0

डबल प्रश्नों को रोकने के लिए, आपको वास्तव में वह सब कुछ लोड करना चाहिए जो आपको लगता है कि आप इसका उपयोग करेंगे। तो, आप घोंसला अपने आदेश documentation पर इस उदाहरण की तरह शामिल करना चाहिए:

users = User.includes(:address, friends: [:address, :followers]) 

तुम भी तरह भी गहरे संबंध जोड़ सकते हैं:

users = User.includes(:address, {friends: [:address, :followers]}) 
+0

यह वही है जो मैं टालना चाहता हूं - मैं लोडिंग आश्रित वस्तुओं को तब तक लोड करना चाहता हूं जब तक यह पता न हो कि मुझे उनकी आवश्यकता है। –

+0

तो, केवल एक चीज जो आपको चाहिए उसे एसोसिएशन विधि द्वारा कॉल करना है: उदाहरण के लिए User.first.address। – Hamdan

+1

@ हैमडैम, वह वास्तव में एक उपयोगकर्ता का उपयोग नहीं कर रहा है, लेकिन कई; आपके उदाहरण में, उत्सुक लोडिंग के बिना एन addional प्रश्न पता – Leito