这是两个简单的模型:
class Post < ActiveRecord::Base
has_one :asset, :dependent => :destroy
validates :asset, presence: true
end
class Asset < ActiveRecord::Base
belongs_to :post
end
我正在尝试创建这样的工厂:
factory :post do
# fields...
asset { FactoryGirl.create(:asset) }
end
factory :asset do
# fields...
post
end
但是,运行规范会进入循环。
我也试过这个:
factory :post do
# fields...
before(:create) do |post, evaluator|
FactoryGirl.create_list(:asset, 1, post: post)
end
end
但结果是“验证失败:资产不能为空”。
我如何表达我的情况?
答案 0 :(得分:30)
我使用after(:build)回调解决了这个问题。
factory :post do
# fields...
after(:build) do |post|
post.asset ||= FactoryGirl.build(:asset, :post => post)
end
end
factory :asset do
# fields...
after(:build) do |asset|
asset.post ||= FactoryGirl.build(:post, :asset => asset)
end
end
通过这种方式,将在保存拥有类之前创建关联对象,因此验证通过。
答案 1 :(得分:2)
验证失败,因为当FactoryGirl
创建Post
时,必须存在资产。因此,在您的FactoryGirl
定义中,您可以创建Asset
作为创建Post
的一部分。插入类似FactoryGirl post.rb
文件的内容:
asset { FactoryGirl.create(:asset) }
或
您可以在规范文件中创建Asset
声明作为Post
声明的一部分,如下所示:
asset = FactoryGirl.create(:asset)
FactoryGirl.create(:post, :asset => asset)
感谢。
答案 2 :(得分:0)
您可以通过以下方式传递子协会来预加载:
FactoryGirl.define do
factory :post do
asset { Asset.create! }
end
end
(更好的是,使用资产工厂生成相关资产并预先设置详细信息。)
另一种手动方式是通过FactoryGirl.create(:asset)创建一个Asset,并将其传递给变量创建,即:
asset = FactoryGirl.create(:asset)
post = FactoryGirl.create(:post, asset: asset)
答案 3 :(得分:0)
错误Validation failed: Asset can't be blank
是因为看起来你的工厂后面有关联关系。
factory :post do
# fields...
end
因此,当您创建post
时,没有asset
,因此验证失败。试试这个
factory :post do
# fields...
asset
end
看看这个wiki page and the associations section。它还解释了create
和build
之间的区别