我遇到了FactoryGirl似乎正在创建具有has_many关系的额外记录的问题。
鉴于这些模型:
class NextAction < ActiveRecord::Base
has_many :next_actions_orders
has_many :orders, through: :next_actions_orders
end
class NextActionsOrder < ActiveRecord::Base
belongs_to :order
belongs_to :next_action
end
class Order < ActiveRecord::Base
has_many :next_actions_orders
has_many :next_actions, through: :next_actions_orders
end
这些工厂:
FactoryGirl.define do
factory :next_action do
status :pending
trait :pickup do
next_actions_orders { FactoryGirl.create_list(:next_actions_order, 1) }
action_type :pickup
end
trait :multiple_pickups do
next_actions_orders { FactoryGirl.create_pair(:next_actions_order) }
action_type :pickup
end
end
end
FactoryGirl.define do
factory :next_actions_order do
order { FactoryGirl.create(:order) }
next_action
end
end
FactoryGirl.define do
factory :order do
status :pending
end
end
正如您在NextAction工厂中看到的,我遇到了设置NextActionOrder关联的问题。
我通常使用next_actions_orders { FactoryGirl.create(:next_actions_order) }
,但使用has_many :next_actions_orders
,我收到了undefined method 'each' for #<NextActionsOrder...
错误。
next_actions_orders { FactoryGirl.create_list(:next_actions_order, 1) }
似乎可以解决这个问题。如下所示,这似乎不是问题的原因,因为它也存在于create_pair
示例中。
真正的问题是:
it 'create_list generates duplicate FactoryGirl records' do
puts NextAction.count # output: 0
pickup = create(:next_action, :pickup)
puts NextAction.count # output: 2
## binding.pry
end
简洁地说,create(:next_action)
调用似乎产生了1个额外的NextAction记录。
我用撬检查这一点,果然,你可以看到这一点。
在上面显示的第一个位置插入pry,查询产生以下内容:
pry(#<RSpec::Core::ExampleGroup::Nested_1>)> NextAction.all
=> [#<NextAction id: 2, ... created_at: "2014-04-20 16:40:57", updated_at: "2014-04-20 16:40:57", status: 0>,
#<NextAction id: 3, ... created_at: "2014-04-20 16:40:57", updated_at: "2014-04-20 16:40:57", status: 0>]
pry(#<RSpec::Core::ExampleGroup::Nested_1>)> NextActionsOrder.all
=> [#<NextActionsOrder id: 1, next_action_id: 3, order_id: 2>]
pry(#<RSpec::Core::ExampleGroup::Nested_1>)> Order.all
=> [#<Order id: 2, created_at: "2014-04-20 16:40:57", updated_at: "2014-04-20 16:40:57", status: 0>]
除了NextAction ID#2之外,一切看起来都很棒。它没有任何关联,它只是因某种原因而创建的孤儿记录。
以下是create_pair
:
it 'create_pair generates duplicate FactoryGirl records' do
puts NextAction.count # output: 0
pickups = create(:next_action, :multiple_pickups)
puts NextAction.count # output: 3
## binding.pry
end
如图所示插入pry,相同的查询产生:
pry(#<RSpec::Core::ExampleGroup::Nested_1>)> NextAction.all
=> [#<NextAction id: 4, created_at: "2014-04-20 16:53:20", updated_at: "2014-04-20 16:53:20", status: 0>,
#<NextAction id: 5, created_at: "2014-04-20 16:53:20", updated_at: "2014-04-20 16:53:20", status: 0>,
#<NextAction id: 6, created_at: "2014-04-20 16:53:20", updated_at: "2014-04-20 16:53:20", status: 0>]
pry(#<RSpec::Core::ExampleGroup::Nested_1>)> NextActionsOrder.all
=> [#<NextActionsOrder id: 2, next_action_id: 6, order_id: 3>,
#<NextActionsOrder id: 3, next_action_id: 6, order_id: 4>]
pry(#<RSpec::Core::ExampleGroup::Nested_1>)> Order.all
=> [#<Order id: 3, created_at: "2014-04-20 16:53:20", updated_at: "2014-04-20 16:53:20", status: 0>,
#<Order id: 4, created_at: "2014-04-20 16:53:20", updated_at: "2014-04-20 16:53:20", status: 0>]
同样,一切看起来都不错,除了现在我们有2个孤儿NextAction记录 - ID#4和#5。
有什么想法吗?非常感谢!
答案 0 :(得分:1)
这是因为工厂中的next_action:next_actions_order,它会创建一个额外的next_action ......
我会使用
重写next_action工厂after(:build) do |next_action, evaluator|
next_action.orders << build(:order)
end
或
after(:build) do |next_action, evaluator|
next_action.orders << build_list(:order, evaluator.orders_count)
end
如果您需要多个。
这样就可以立即创建整个链,所有交叉引用都应该填充! (没有双打!)