rspec Has_many एसोसिएशन के साथ फैक्टरीगर्ल में फैक्ट्री कैसे स्थापित करें




ruby-on-rails-3.1 has-many-through (4)

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

मेरे पास निम्नलिखित मॉडल हैं जिनमें 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

मैं Rails 3.1.rc4, फैक्टरीगर्ल 2.0.2, factory_girl_rails 1.1.0, और rspec का उपयोग कर रहा हूं। यहां मेरे मूल आरएसपीसी आरएसपीसी सैनिटी चेक के लिए है :listing कारखाना:

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> को undefined method 'each' for #<Feature> जिसे मैंने सोचा था क्योंकि listing.featuresundefined method 'each' for #<Feature> एक सरणी लौटाती हैं। तो मैंने इसे बदल दिया

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

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


मैंने कुछ अलग दृष्टिकोणों की कोशिश की और यह वह है जो मेरे लिए सबसे अधिक भरोसेमंद काम करता है (आपके मामले में अनुकूलित)

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

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

# 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)

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


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

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

आप 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