谁能告诉我,如果我只是去有关安装错误的方式?
我有以下型号有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,1.1.0 factory_girl_rails,和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
难道仅仅是不明智的可发电工厂对象这样,还是我缺少什么?非常感谢任何和所有输入!
创建这类协会要求使用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
另外,您也可以使用块并跳过association
关键字。这使得人们有可能建立对象,而不保存到数据库中(否则,一个的has_many协会将你的记录保存到数据库,即使你使用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
,如果你需要的DB创建:
...
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
我尝试了几种不同的方法,这是大多数工作可靠,我的一个(适用于你的情况)
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)
希望帮助。