2012-06-01 9 views
10

के साथ सहयोग बनाते हैं मैं फैक्टरीगर्ल में नया हूं और मैं निम्नलिखित सरल परिदृश्य की कोशिश कर रहा हूं?फैक्टरी गर्ल मौजूदा ऑब्जेक्ट

factory :female, :class => Gender do 
    code 'Female' 
end 

factory :male, :class => Gender do 
    code 'Male' 
end 

factory :papas, :class => Customer do 
    first_name 'Jim' 
    last_name 'Papas' 
    association :gender, :factory => :male, :strategy => :build 
end 

factory :dumas, :class => Customer do 
    first_name 'Mary' 
    last_name 'Dumas' 
    association :gender, :factory => :female, :strategy => :build 
end 
फिर अपने परीक्षण में

:

create(:male) 
create(:female) 
create(:papas) 
create(:dumas) 

ध्यान दें कि ग्राहक वर्ग एक एसोसिएशन belongs_toGender वर्ग और एक सत्यापन नियम है कि का कहना है कि gender_id मौजूद होना चाहिए है। कोड पर विशिष्टता के लिए मेरे पास Gender कक्षा पर भी एक सत्यापन है।

पर create(:papas) ऊपर बयान, अपने परीक्षण में, मैं त्रुटि है कि Customer जाता है कि बनाया जा रहा मान्य नहीं है, क्योंकि gender_idnil है।

अगर मैं लिंग के साथ :strategy => :buildCustomer:papas पर कारखाना संघ को निकालते हैं, तो मैं एक त्रुटि प्राप्त होगी, कि जब :papas बनाने का प्रयास कर, लिंग के लिए कोड पहले से मौजूद है।

मुझे ऐसा करने की क्या ज़रूरत है ताकि मेरे परीक्षण ऊपर आवश्यकतानुसार डेटा बना सकें?

ध्यान दें कि मैं अन्य परीक्षणों में ग्राहकों के बिना भी गेंडर्स बनाना चाहता हूं। फैक्ट्री बनाने के साथ ग्राहकों को बनाने के लिए मुझे मत कहें और ग्राहकों को एक ही समय में लिंग बनाने दें। अगर मैं एक ही लिंग के दो ग्राहकों को बनाने की कोशिश करता हूं तो यह काम नहीं करेगा।

@male = create(:male) 
@female = create(:female) 
create(:papas, :gender => @male) 
create(:dumas, :gender => @female) 

(।? जुड़नार का उपयोग करते समय इन बातों थे तैयार आउट-ऑफ-द-बॉक्स मैं वापस जुड़नार पर लौटने दूँ)

:

इसके अलावा, वहाँ एक से एक बेहतर जवाब हो गया है

उत्तर

14

आप अपने लिंग उदाहरणों के लिए कारखाने का उपयोग न करने और अपने ग्राहक कारखाने में कॉलबैक का उपयोग करके दोनों जो चाहते हैं उसे प्राप्त कर सकते हैं।

आप लिंग कारखाने से बहुत कुछ प्राप्त नहीं कर रहे हैं क्योंकि यह खड़ा है (हालांकि मैं इस प्रश्न पूछने के प्रयोजनों के लिए इसे सरल बना सकता हूं)। कॉलबैक का उपयोग करके factory_girl है में के लिए

factory :dumas, :class => Customer do 
    first_name 'Mary' 
    last_name 'Dumas' 
    before_create do |customer| 
    customer.gender = Gender.find_or_create_by_code!('Female') 
    end 
end 

प्रारूप: लिंग स्थापित करने के लिए

Gender.find_or_create_by_code!('Male') 

फिर अपने ग्राहक कारखाने में आप एक कॉलबैक से पहले उपयोग कर सकते हैं: आप बस के रूप में आसानी से एक लिंग प्राप्त करने के लिए ऐसा कर सकता है हाल ही में, इसलिए यदि आप 3.3 का उपयोग कर रहे बदल गया है या बाद में आप क्या करने की आवश्यकता होगी:

before(:create) do |customer| 
बजाय

before_create

यदि लिंग बनाना आपके उदाहरण से अधिक जटिल है तो आप अभी भी एक कारखाने का उपयोग करके लिंग बना सकते हैं, लेकिन find_by_code!find_or_create_by_code! का उपयोग करके कॉलबैक का उपयोग करके अपने ग्राहकों के साथ उन्हें हुक कर सकते हैं।

+0

हालांकि काफी वर्बोज़ जुड़नार बनाम, आपका जवाब सही है। मैं पिछले दो महीनों में कारखाने की लड़की का उपयोग कर रहा हूं और अभी भी मेरी अगली परियोजना फिक्स्चर के साथ होगी! –

+1

कारखानों के साथ आपको जो लाभ मिल सकता है वह है यदि आपको कई अलग-अलग ग्राहकों को बनाने की आवश्यकता है। आपके पास पुरुष_customer और female_customer फैक्ट्री हो सकती है और उनको अपने अलग-अलग ग्राहकों के लिए मूल कारखानों के रूप में उपयोग कर सकती है - जो वर्बोजिटी को काफी कम कर देती हैं। खुशी है कि यह काम किया हालांकि! – Shadwell

5

ignore ब्लॉक इस रूप में अच्छी तरह लपेट के लिए इस्तेमाल किया जा सकता:

factory :dumas, :class => Customer do 
    ignore do 
    female { Gender.find_by_code('Female') || create(:female) } 
    end 

    first_name 'Mary' 
    last_name 'Dumas' 
    gender { female } 
end 
5

ignore पदावनत किया गया है और फैक्टरी लड़की के संस्करण 5 पर निकाल दिया जाएगा।

इसके बजाय, आप transient attributes उपयोग कर सकते हैं:

factory :dumas, :class => Customer do 
    transient do 
    female { Gender.find_by_code('Female') || create(:female) } 
    end 

    first_name 'Mary' 
    last_name 'Dumas' 
    gender { female } 
end