如何在 FactoryBot 中使用 has_many 关联设置工厂
有人可以告诉我我是否以错误的方式进行设置吗?
我有以下具有 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。这是我对 :listing
工厂的基本 rspec rspec 健全性检查:
it "creates a valid listing from factory" do
Factory(:listing).should be_valid
end
这是 Factory(:listing)
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
错误消息是 #
的未定义方法“each”,我认为这对我来说有意义,因为 listing.features
返回一个数组。所以我将其更改为
association :features, [:factory => :feature]
,现在收到的错误是 ArgumentError: Not Registration: features
以这种方式生成工厂对象是不明智的,还是我错过了什么?非常感谢您的所有意见!
Can someone tell me if I'm just going about the setup the wrong way?
I have the following models that have has_many.through associations:
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
I'm using Rails 3.1.rc4, FactoryGirl 2.0.2, factory_girl_rails 1.1.0, and rspec. Here is my basic rspec rspec sanity check for the :listing
factory:
it "creates a valid listing from factory" do
Factory(:listing).should be_valid
end
Here is Factory(:listing)
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
The :listing_feature
and :feature
factories are similarly setup.
If the association :features
line is commented out, then all my tests pass.
When it is
association :features, :factory => :feature
the error message isundefined method 'each' for #<Feature>
which I thought made sense to me because because listing.features
returns an array. So I changed it to
association :features, [:factory => :feature]
and the error I get now is ArgumentError: Not registered: features
Is it just not sensible to be generating factory objects this way, or what am I missing? Thanks very much for any and all input!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
或者,您可以使用块并跳过
association
关键字。这使得无需保存到数据库即可构建对象(否则,即使您使用build
函数而不是create
,has_many 关联也会将您的记录保存到数据库中)。Alternatively, you can use a block and skip the
association
keyword. This makes it possible to build objects without saving to the database (otherwise, a has_many association will save your records to the db, even if you use thebuild
function instead ofcreate
).创建此类关联需要使用 FactoryGirl 的回调。
可以在这里找到一组完美的示例。
https://thoughtbot.com/blog/aint-no-calla-back-girl
将其带入您的示例中。
Creating these kinds of associations requires using FactoryGirl's callbacks.
A perfect set of examples can be found here.
https://thoughtbot.com/blog/aint-no-calla-back-girl
To bring it home to your example.
您可以使用
trait
:如果您需要创建数据库,则使用
callback
:在您的规范中使用如下所示:
这将消除工厂中的重复并更具可重用性。
https://robots.thoughtbot.com/remove-duplication-with-factorygirls-traits
You could use
trait
:With
callback
, if you need DB creation:Use in your specs like this:
This will remove duplication in your factories and be more reusable.
https://robots.thoughtbot.com/remove-duplication-with-factorygirls-traits
我尝试了几种不同的方法,这是对我来说最可靠的方法(适合您的情况)
I tried a few different approaches and this is the one that worked most reliably for me (adapted to your case)
从 FactoryBot v5 开始,关联保留了构建策略。关联是解决此问题的最佳方法,文档提供了很好的示例it:
或者控制计数:
Since FactoryBot v5, associations preserve build strategy. Associations are the best way to solve this and the docs have good examples for it:
Or with control over the count:
与 @thisismydesign 类似,但它在我这边创建了一个额外的
post
(FactoryBot v6.2)。为了避免这种情况,我添加了关键字
instance
,如下所示:Similar to @thisismydesign, however it created an additional
post
on my end (FactoryBot v6.2).To avoid this situation, I've added keyword
instance
as below:这是我的设置方式:
然后在您的测试中您可以执行以下操作:
希望有所帮助。
Here is how I set mine up:
And then in your tests you can do:
Hope that helps.