如何用has_many关联在FactoryGirl中设置工厂
有人能告诉我,如果我只是在错误的方式进行安装?
我有以下有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,FactoryGirl 2.0.2,factory_girl_rails 1.1.0和rspec。 这里是我的基本rspec 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行被注释掉了,那么我所有的testing都会通过。 
 几时 
 association :features, :factory => :feature 
 错误消息是undefined method 'each' for #<Feature>我认为对我有意义,因为listing.features返回一个数组。 所以我改变了 
 association :features, [:factory => :feature] 
 和我现在得到的错误是ArgumentError: Not registered: features是这样生成工厂对象是不明智的,或者我错过了什么? 非常感谢任何和所有的input! 
创build这些types的关联需要使用FactoryGirl的callback。
一个完美的例子可以在这里find。
http://robots.thoughtbot.com/post/254496652/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 
 或者,您可以使用块并跳过association关键字。 这使得构build对象而不保存到数据库成为可能(否则,即使使用build函数而不是create ,has_many关联会将logging保存到数据库中)。 
 FactoryGirl.define do factory :listing_with_features, :parent => :listing do |listing| features { build_list :feature, 3 } end end 
我尝试了一些不同的方法,这对我来说是最可靠的(适应你的情况)
 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 
 你可以使用trait : 
 FactoryGirl.define do factory :listing do ... trait :with_features do features { build_list :feature, 3 } end end end 
 有了callback ,如果你需要创build数据库: 
 ... 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
这是我如何设置我的:
 # 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 
然后在你的testing中,你可以这样做:
 @preference_set = FactoryGirl.create(:preference_set_with_preferences) 
希望有所帮助。