FactoryGirl与has_many关联创建额外的记录 [英] FactoryGirl creating extra records with has_many association

查看:105
本文介绍了FactoryGirl与has_many关联创建额外的记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到一个问题,即FactoryGirl似乎正在创建具有has_many关系的额外记录.

I'm running into an issue where FactoryGirl appears to be creating extra records with a has_many relationship.

给出以下模型:

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关联的问题.

As you can see in the NextAction factory, I ran into an issue setting up the NextActionOrder association.

我通常会使用next_actions_orders { FactoryGirl.create(:next_actions_order) },但是使用has_many :next_actions_orders时,会出现undefined method 'each' for #<NextActionsOrder...错误.

I would usually have used next_actions_orders { FactoryGirl.create(:next_actions_order) } but with the has_many :next_actions_orders, I was getting an undefined method 'each' for #<NextActionsOrder... error.

next_actions_orders { FactoryGirl.create_list(:next_actions_order, 1) }似乎可以解决.如下所示,这似乎不是问题的原因,因为在create_pair示例中也存在.

next_actions_orders { FactoryGirl.create_list(:next_actions_order, 1) } seems to work as a workaround. As shown below, this doesn't seem to be the cause of the issue, since it also exists from the create_pair example.

真正的问题是这样:

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记录.

Succinctly, the create(:next_action) calls seem to be generating 1 additional NextAction record than is required.

我用撬子检查了一下,果然可以看到.

I used pry to inspect this and sure enough, you can see this.

在上面显示的第一个位置插入撬动后,查询将产生以下结果:

With pry inserted at the first location shown above, queries produce the following:

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之外,一切看起来都很不错.它在任何地方都没有关联,只是出于某种原因而创建的孤立记录.

Here, everything looks great, except for NextAction ID #2. It's not associated anywhere, it's just an orphan record that was created for some reason.

这是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

插入如图所示的撬,产生相同的查询:

With pry inserted as shown, the same queries produce:

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.

Again, everything looks good, except now we have 2 orphan NextAction records - IDs #4 and #5.

有什么想法吗?非常感谢!

Any ideas? Thanks so much!

推荐答案

这是因为工厂中的next_action:next_actions_order会创建一个额外的next_action ...

It's because of the next_action in the factory :next_actions_order, which creates an additional 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

如果您需要多个.

这样,可以立即创建整个链,并按需填写所有交叉引用! (并且没有双打!)

This way the entire chain is created at once with all cross references filled in as they should! (and without doubles!)

这篇关于FactoryGirl与has_many关联创建额外的记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆