Factory_irl में कारखाना कैसे स्थापित करें has_many एसोसिएशन के साथ


89

क्या कोई मुझे बता सकता है कि क्या मैं सेटअप के बारे में गलत तरीके से जा रहा हूं?

मेरे पास निम्नलिखित मॉडल हैं जिनमें has_many.through एसोसिएशन हैं:

class Listing < ActiveRecord::Base
  attr_accessible ... 

  has_many :listing_features
  has_many :features, :through => :listing_features

  validates_presence_of ...
  ...  
end


class Feature < ActiveRecord::Base
  attr_accessible ...

  validates_presence_of ...
  validates_uniqueness_of ...

  has_many :listing_features
  has_many :listings, :through => :listing_features
end


class ListingFeature < ActiveRecord::Base
  attr_accessible :feature_id, :listing_id

  belongs_to :feature  
  belongs_to :listing
end

मैं रेलिंग 3.1.rc4, FactoryGirl 2.0.2, factory_girl_rails 1.1.0 और rspec का उपयोग कर रहा हूं। यहाँ :listingकारखाने के लिए मेरा मूल rspec rspec पवित्रता जाँच है :

it "creates a valid listing from factory" do
  Factory(:listing).should be_valid
end

यहाँ कारखाना है (लिस्टिंग)

FactoryGirl.define do
  factory :listing do
    headline    'headline'
    home_desc   'this is the home description'
    association :user, :factory => :user
    association :layout, :factory => :layout
    association :features, :factory => :feature
  end
end

:listing_featureऔर :featureकारखानों इसी तरह सेटअप कर रहे हैं।
यदि association :featuresलाइन पर टिप्पणी की जाती है, तो मेरे सभी परीक्षण पास हो जाते हैं।
जब यह है

association :features, :factory => :feature

त्रुटि संदेश वह है undefined method 'each' for #<Feature> जो मैंने सोचा कि मेरे लिए समझ में आता है क्योंकि listing.featuresएक सरणी देता है। इसलिए मैंने इसे बदल दिया

association :features, [:factory => :feature]

और अब मुझे जो त्रुटि मिल रही है, ArgumentError: Not registered: features क्या यह कारखाना वस्तुओं को इस तरह से पैदा करने के लिए समझदार नहीं है, या मैं क्या याद कर रहा हूं? किसी भी और सभी इनपुट के लिए बहुत बहुत धन्यवाद!

जवाबों:


57

इस प्रकार के संघों को बनाने के लिए FactoryGirl के कॉलबैक का उपयोग करने की आवश्यकता होती है।

उदाहरणों का एक आदर्श सेट यहाँ पाया जा सकता है।

https://thoughtbot.com/blog/aint-no-calla-back-girl

इसे अपने उदाहरण के लिए घर लाने के लिए।

Factory.define :listing_with_features, :parent => :listing do |listing|
  listing.after_create { |l| Factory(:feature, :listing => l)  }
  #or some for loop to generate X features
end

क्या आपने एसोसिएशन: सुविधाओं, [: फ़ैक्टरी =>: फ़ीचर] का उपयोग किया था?
davidtingsu

108

वैकल्पिक रूप से, आप एक ब्लॉक का उपयोग कर सकते हैं और associationकीवर्ड को छोड़ सकते हैं। यह डेटाबेस को सहेजे बिना ऑब्जेक्ट्स का निर्माण करना संभव बनाता है (अन्यथा, एक has_many एसोसिएशन आपके रिकॉर्ड को db में बचाएगा, भले ही आप buildफ़ंक्शन का उपयोग करें create)।

FactoryGirl.define do
  factory :listing_with_features, :parent => :listing do |listing|
    features { build_list :feature, 3 }
  end
end

5
यह बिल्ली की म्याऊ है। दोनों की क्षमता buildऔर createइसे सबसे बहुमुखी पैटर्न बनाती है। तो फिर इस कस्टम FG निर्माण रणनीति का उपयोग gist.github.com/Bartuz/74ee5834a36803d712b7 को post nested_attributes_forजब नियंत्रक कार्यों का परीक्षण है किaccepts_nested_attributes_for
क्रिस बेक

4
upvoted, स्वीकृत उत्तर IMO की तुलना में कहीं अधिक पठनीय और बहुमुखी है
m_x

1
FactoryBot 5 के अनुसार, associationकीवर्ड माता-पिता और बच्चे के लिए एक ही बिल्ड रणनीति का उपयोग करता है। तो, यह डेटाबेस के लिए वस्तुओं w / o बचत बना सकते हैं।
निक

27

आप उपयोग कर सकते हैं trait:

FactoryGirl.define do
  factory :listing do
    ...

    trait :with_features do
      features { build_list :feature, 3 }
    end
  end
end

साथ callback, आप डीबी निर्माण की जरूरत है:

...

trait :with_features do
  after(:create) do |listing|
    create_list(:feature, 3, listing: listing)
  end
end

इस तरह से अपने चश्मे का उपयोग करें:

let(:listing) { create(:listing, :with_features) }

यह आपके कारखानों में दोहराव को दूर करेगा और अधिक पुन: प्रयोज्य होगा।

https://robots.thoughtbot.com/remove-duplication-with-factorygirls-traits


20

मैंने कुछ अलग तरीकों की कोशिश की और यह वह है जिसने मेरे लिए सबसे मज़बूती से काम किया (आपके मामले के अनुकूल)

FactoryGirl.define do
  factory :user do
    # some details
  end

  factory :layout do
    # some details
  end

  factory :feature do
    # some details
  end

  factory :listing do
    headline    'headline'
    home_desc   'this is the home description'
    association :user, factory: :user
    association :layout, factory: :layout
    after(:create) do |liztng|
      FactoryGirl.create_list(:feature, 1, listing: liztng)
    end
  end
end

0

यहां बताया गया है कि मैंने अपना सेट अप कैसे किया:

# Model 1 PreferenceSet
class PreferenceSet < ActiveRecord::Base
  belongs_to :user
  has_many :preferences, dependent: :destroy
end

#Model 2 Preference

class Preference < ActiveRecord::Base    
  belongs_to :preference_set
end



# factories/preference_set.rb

FactoryGirl.define do
  factory :preference_set do
    user factory: :user
    filter_name "market, filter_structure"

    factory :preference_set_with_preferences do
      after(:create) do |preference|
        create(:preference, preference_set: preference)
        create(:filter_structure_preference, preference_set: preference)
      end
    end
  end

end

# factories/preference.rb

FactoryGirl.define do
  factory :preference do |p|
    filter_name "market"
    filter_value "12"
  end

  factory :filter_structure_preference, parent: :preference do
    filter_name "structure"
    filter_value "7"
  end
end

और फिर अपने परीक्षणों में आप कर सकते हैं:

@preference_set = FactoryGirl.create(:preference_set_with_preferences)

उम्मीद है की वो मदद करदे।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.