2013-04-30 5 views
22

की विशेषता ओवरराइड करें यह शायद मूर्खतापूर्ण सरल है लेकिन मुझे कहीं भी एक उदाहरण नहीं मिल रहा है।फैक्ट्रीगर्ल संबंधित ऑब्जेक्ट

FactoryGirl.define do 
    factory :profile do 
    user 

    title "director" 
    bio "I am very good at things" 
    linked_in "http://my.linkedin.profile.com" 
    website "www.mysite.com" 
    city "London" 
    end 
end 

FactoryGirl.define do 
    factory :user do |u| 
    u.first_name {Faker::Name.first_name} 
    u.last_name {Faker::Name.last_name} 

    company 'National Stock Exchange' 
    u.email {Faker::Internet.email} 
    end 
end 

क्या मैं उपयोगकर्ता से कुछ को ओवरराइड है क्या करना चाहते हैं जब मैं एक प्रोफ़ाइल बनाने का श्रेय:

मैं दो कारखानों है

p = FactoryGirl.create(:profile, user: {email: "[email protected]"}) 

या कुछ इसी तरह है, लेकिन मैं नहीं कर सकता सिंटैक्स सही प्राप्त करें। त्रुटि:

ActiveRecord::AssociationTypeMismatch: User(#70239688060520) expected, got Hash(#70239631338900) 

मैं जानता हूँ कि मैं उपयोगकर्ता पहले बनाने और फिर प्रोफ़ाइल से संबद्ध करके ऐसा कर सकते हैं, लेकिन मैंने सोचा था कि एक बेहतर तरीका होना चाहिए।

या यह काम करेगा:

p = FactoryGirl.create(:profile, user: FactoryGirl.create(:user, email: "[email protected]")) 

लेकिन यह बहुत जटिल लगता है। क्या किसी संबद्ध विशेषता को ओवरराइड करने का कोई आसान तरीका नहीं है? इसके लिए सही वाक्यविन्यास क्या है ??

उत्तर

6

मुझे लगता है कि आप यह काम कॉलबैक और क्षणिक विशेषताओं के साथ कर सकते हैं। तुम इतनी तरह अपने प्रोफ़ाइल कारखाने को संशोधित करते हैं:

FactoryGirl.define do 
    factory :profile do 
    user 

    ignore do 
     user_email nil # by default, we'll use the value from the user factory 
    end 

    title "director" 
    bio "I am very good at things" 
    linked_in "http://my.linkedin.profile.com" 
    website "www.mysite.com" 
    city "London" 

    after(:create) do |profile, evaluator| 
     # update the user email if we specified a value in the invocation 
     profile.user.email = evaluator.user_email unless evaluator.user_email.nil? 
    end 
    end 
end 

तो आप इस तरह यह नारा है और वांछित परिणाम प्राप्त करने के लिए सक्षम होना चाहिए:

p = FactoryGirl.create(:profile, user_email: "[email protected]") 

मैं इसे, हालांकि परीक्षण नहीं किया।

+0

धन्यवाद, लेकिन मैं चाहता हूं कि यह किसी भी विशेषता के लिए काम करे, इसलिए मैं इसे प्रत्येक के लिए कोड नहीं करना चाहता। शायद किसी और को इसकी जरूरत नहीं है ... – bobomoreno

+2

मुझे लगता है कि आपके उदाहरण में एक त्रुटि है। 'After (: create)' को 'profile.user.email = मूल्यांकनकर्ता.user_email' के रूप में बदलें जब तक मूल्यांकनकर्ता.user_email.nil? ' – Kelly

18

फैक्टरीगर्ल के रचनाकारों में से एक के अनुसार, आप एसोसिएशन सहायक (Pass parameter in setting attribute on association in FactoryGirl) में गतिशील तर्क पारित नहीं कर सकते हैं।

FactoryGirl.define do 
    factory :profile do 
    transient do 
     user_args nil 
    end 
    user { build(:user, user_args) } 

    after(:create) do |profile| 
     profile.user.save! 
    end 
    end 
end 

तो फिर तुम यह कॉल कर सकते हैं लगभग तरह आप चाहते थे:

हालांकि, अगर आप इस तरह कुछ करने के लिए सक्षम होना चाहिए

p = FactoryGirl.create(:profile, user_args: {email: "[email protected]"}) 
+2

ग्रेट उत्तर। क्या आप नवीनतम रेल संस्करणों का अनुपालन करने के लिए इसे अपडेट करेंगे। उदाहरण के लिए। मुझे एक "अस्वीकरण चेतावनी मिल रही है:' # अनदेखा 'बहिष्कृत है और इसे 5.0 में हटा दिया जाएगा। " इस जवाब को लागू करते समय। –

+0

मुझे रेलवे 5 –

+0

में पहले से ही यह समस्या है, आप चेतावनी से छुटकारा पाने के लिए "अनदेखा" के बजाय "क्षणिक" का उपयोग कर सकते हैं –

3

उपयोगकर्ता बनाने के लिए पहले से यह हल है, और फिर प्रोफ़ाइल :

my_user = FactoryGirl.create(:user, user_email: "[email protected]") 
my_profile = FactoryGirl.create(:profile, user: my_user.id) 

तो, यह प्रश्न में लगभग समान है, दो पंक्तियों में विभाजित है। केवल वास्तविक अंतर ".id" की स्पष्ट पहुंच है। रेल के साथ परीक्षण 5.

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