2013-05-27 4 views
30

रेल 3.2+ में, आप यह कर सकते हैंक्या has_many एसोसिएशन पर "first_or_build" विधि है? इसका मतलब है आप भी कर सकते हैं</p> <pre><code>SomeModel.some_scope.first_or_initialize </code></pre> <p>:

OtherModel.some_models.first_or_initialize 

मैं इस सुंदर उपयोगी पाते हैं, लेकिन मैं पर एक first_or_build विधि करना चाहते हैं मेरी has_many संघों, जो first_or_initialize की तरह काम करते हैं लेकिन भी build के रूप में संघ के लिए एक नया रिकॉर्ड जोड़ने जब की जरूरत है। स्पष्टीकरण के लिए

अद्यतन: हाँ, मैं के बारे में first_or_initialize और first_or_create पता है। बात यह है कि first_or_initializebuild के रूप में एसोसिएशन के लक्ष्य में प्रारंभिक रिकॉर्ड नहीं जोड़ता है, और first_or_create ... अच्छी तरह से ... एक रिकॉर्ड बनाता है, जो इरादा नहीं है।

class OtherModel < ActiveRecord::Base 

    has_many :some_models do 
    def first_or_build(attributes = {}, options = {}, &block) 
     object = first_or_initialize(attributes, options, &block) 
     proxy_association.add_to_target(object) if object.new_record? 
     object 
    end 
    end 

end 

मैं सिर्फ अगर आश्चर्य है: इस समस्या का

  • निर्मित समाधान पहले से ही मौजूद

    मैं एक समाधान है कि काम करता है, संघ एक्सटेंशन का उपयोग किया है?

  • मेरी कार्यान्वयन खामियों मैं नहीं दिख रहा है?
+0

यदि आप किसी अन्य बिंदु पर 'अन्य मॉडेल.some_models' पर उत्सुक लोडर करना चाहते हैं तो क्या होगा? मैं बजाय 'after_initialize' कॉलबैक में इस तरह के प्रारंभिक प्रदर्शन करना चाहता हूं, यह बहुत साफ दृष्टिकोण आईएमओ है। –

उत्तर

19

मैं अगर वहाँ रेल कि वास्तव में आप क्या चाहते हो जाएगा में बनाया गया कुछ भी है यकीन नहीं है, लेकिन आप की तुलना में आप वर्तमान में उपयोग कर रहे हैं अधिक संक्षिप्त विस्तार है, जो मेरा मानना ​​है कि साथ first_or_initialize कोड की नकल कर सकता है कि तुम क्या चाहते हैं, और इसे एक पुन: प्रयोज्य एक्सटेंशन में लपेटें जैसे कि निम्न। यह रेल 3.2 विस्तार प्रारूप के साथ लिखा गया है।

module FirstOrBuild 
    def first_or_build(attributes = nil, options = {}, &block) 
    first || build(attributes, options, &block) 
    end 
end 

class OtherModel < ActiveRecord::Base 
    has_many :some_models, :extend => FirstOrBuild 
end 
+0

काफी सही। मुझे नहीं पता कि मैंने इस तरह से अधिक क्यों किया, यह स्पष्ट रूप से बेहतर है। –

+4

आदेश में इस रेल 4.1.0.beta में काम करने के लिए पाने के लिए, मैं scoping संदर्भ अंदर प्रॉक्सी संघ निर्दिष्ट करने के लिए था, जैसे कि एक्सटेंशन 'पहला || पढ़ता है स्कॉइंग {proxy_association.build (विशेषताएँ, और ब्लॉक)} '(कहीं भी विकल्पों के बिना) और आमंत्रण' Post.first.comments.where (foo: 'bar') जैसा दिखता है। first_or_build'। इसके अलावा, मैं नई वाक्य रचना has_many प्रयोग किया है:। पदों, - अद्यतन के लिए> पोस्ट पर {FirstOrBuild विस्तार}) –

+0

@ChrisKeele धन्यवाद। क्या यह अभी भी इरादे के रूप में काम करता है जब आप 'foo.bars.where (शीर्षक:' buzz ') जैसी चीजें करते हैं। First_or_build'? (यानी foo.bars में एक नया बार जोड़ा जाता है, और इसमें शीर्षक के रूप में 'buzz' है)। एक साइड नोट के रूप में, मैंने अभी देखा है कि first_or_create proxy_association के लक्ष्य को रिकॉर्ड नहीं जोड़ता है, या तो। शायद मैं रेल टीम के लिए एक टिकट दायर करनी चाहिए, एपीआई की वर्तमान स्थिति कम से कम आश्चर्य की बात है के सिद्धांत का पालन नहीं करता IMHO –

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