2015-12-27 12 views
8

मेरी मूल कक्षा कभी-कभी बच्चे द्वारा after_save कॉलबैक में अपने सभी बच्चों को लोड नहीं कर रही है।रेल एसोसिएशन सही ढंग से लोड नहीं हो रहा है

class Parent < ActiveRecord::Base 
    has_many :children 

    def update_something 
    # explained below 
    end 
end 

class Child < ActiveRecord::Base 
    belongs_to :parent 

    after_save :tell_parent_to_update 

    def tell_parent_to_update 
    parent.update_something 
    end 
end 

मैं जो सिर्फ 2 बातें की जाँच करता है एक परीक्षण मैं इस पर चल रहा हूँ, है:

मैं दो मॉडल है। parent.children.count और parent.children.lengthदोनों होना चाहिए 4. मुझे एहसास है कि गिनती कभी-कभी अलग होती है, लेकिन (जहां तक ​​मुझे पता है) यह यहां नहीं होना चाहिए।

अगर मैं update_something परिभाषित बस दोहराना चाहते children से अधिक:

def update_something 
    children.each do |child| 
    end 
end 

परीक्षण विफल रहता है - पाश एक बार निष्पादित करेंगे (और एक भी बच्चे की सरणी वापस आ जाएगी - पहलेchild बनाई गई) ।

अन्यथा, मैं तब तक कोई कोड डाल सकता हूं जब तक यह children का उल्लेख नहीं करता है और यह काम करेगा। यह बच्चों के लिए कॉल की तरह है जो एसोसिएशन को गलत चीज़ लोड करने का कारण बन रहा है।

एक रीलोड जबरदस्ती यह ठीक करता है:

def update_something 
    children(true).each do |child| 
    end 
end 

लेकिन इस hacky है और मैं नहीं बल्कि यदि संभव हो तो जड़ इस मुद्दे को ठीक होगा।

क्या यह मेरी बग, या रेल बग है (और यदि ऐसा है तो मैं इसे पाने के लिए कुछ कर सकता हूं)?

मुझे शक है कि यह महत्वपूर्ण है लेकिन यह sqlite3 का उपयोग कर एक परीक्षण वातावरण है। हालांकि यह एक देव वातावरण में भी विफल हो जाएगा यदि मैं एक एकल कंसोल सत्र में रिकॉर्ड्स बना और परीक्षण करता हूं।

+0

'बच्चे.चलो करते हैं | बच्चे | 'या' बच्चे.चलो करते हैं | बच्चे | '? –

+0

शायद कीवर्ड के साथ कुछ करने के लिए, बस अनुमान लगाया। – Nithin

+0

मैंने पहले भी सोचा था, लेकिन वास्तविक कोड में यह अब बहुत अलग है, और मॉडल/विधियों के वास्तविक नाम बेहद डोमेन-विशिष्ट हैं और दुर्भाग्यवश कीवर्ड नहीं हैं –

उत्तर

3

अंधेरे में वार, लेकिन आप inverse_of, जो मैं भंडार का मानना ​​है कि एक ही स्मृति ब्लॉक में संबद्ध वस्तुओं की आवश्यकता हो सकती, के रूप में विभिन्न ब्लॉकों का विरोध करने के लिए एक मानक दृष्टिकोण बनाना होगा:

#app/models/parent.rb 
class Parent < ActiveRecord::Base 
    has_many :children, inverse_of: :parent 
    ... 
end 

#app/models/child.rb 
class Child < ActiveRecord::Base 
    belongs_to :parent, inverse_of: :children 
    ... 
end 

मेरे अपने में अनुभव, मैंने पाया है inverse_of आपको अन्य मॉडलों में सहयोगी डेटा को कॉल करने की अनुमति देता है। उदाहरण के लिए, parent.update_somethinginverse_of पर कॉल करने से या तो एक त्रुटि हो सकती है (यदि parent स्पष्ट रूप से परिभाषित नहीं किया गया था), या parent ऑब्जेक्ट को फिर से बनाना होगा।

good write-up here है।

-

अगर यह मदद नहीं करता है तो मैं जवाब हटा दूंगा।

+0

दुर्भाग्य से इसे ठीक नहीं लग रहा था। लिखने के अनुसार और जो मुझे ऑनलाइन मिला, रेल के रूप में 4.1 (मैं 4.2 हूं) यह स्वचालित रूप से इसे संभाला जा रहा है। हालांकि यह जवाब छोड़ने के लिए उपयोगी होगा हालांकि, अगर यह भविष्य में किसी के लिए इसे ठीक करता है। –

+0

ठीक है, हेड-अप के लिए धन्यवाद। मैं इसे जन्म के लिए छोड़ दूंगा! –

0

यह शायद इसलिए है क्योंकि माता-पिता के बच्चे tell_parent_to_update चलाने से पहले आपके कोड में किसी बिंदु पर उत्सुक हैं।

parent.children.count एक SQL क्वेरी चलाएगा और डीबी में उपस्थित बच्चों के # को वापस करेगा, जबकि parent.children.length बच्चों की सरणी की लंबाई लौटाएगा (जो शायद पहले से ही उत्सुक है)।

मैं सुझाव दूंगा कि आप मैन्युअल रूप से रेल कंसोल से 1 बच्चों को ऑब्जेक्ट को सहेजने का प्रयास करें और देखें कि अपडेट_समूह में बच्चों की लंबाई और गिनती समान है या नहीं। यदि ऐसा है, तो आपका परीक्षण संभवतः कुछ कोड के कारण विफल हो रहा है।

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