在FactoryGirl中设置关联属性时如何传递参数

33
我想通过一个参数传递到工厂中,用于设置关联模型上的属性。这个关联模型是在工厂内创建的。
我有一个 Transaction 模型,通过 join 表 TxLink 与其自身形成多对多的连接。我想调用 link = FactoryGirl.create(:link_red_to_sub, sub: 10, red: 7) 来创建两个 Transaction 对象和一个将两个对象链接起来的 TxLink。
由于末尾的 units: sub,在关联行中出现了“trait not defined”的错误。我尝试了使用花括号包裹的units: {sub},但不起作用。
factory :tx_link do
    units "9.99"

    factory :link_red_to_sub do
      ignore do
        sub 0
        red 0
      end
      units { red }

      association :giver, factory: :transaction, units: sub
      association :taker, factory: :redemption, units: red
    end
  end
2个回答

41

在 factory_girl 中,association 助手无法接受动态属性参数,但您可以使用动态属性来实例化关联对象:

factory :tx_link do
  units "9.99"

  factory :link_red_to_sub do
    transient do
      sub 0
      red 0
    end
    units { red }

    giver { create(:transaction, units: sub) }
    taker { create(:redemption, units: red) }
  end
end
这种方法唯一的缺陷在于,`giver` 和 `taker` 的关联将始终使用创建策略,而不管您使用何种策略来构建 `tx_link`,这实际上意味着 `attributes_for` 和 `build_stubbed` 对于 `tx_link` 工厂将无法正确工作。提供的示例需要版本4.5.0。

忽略已被弃用。相反,我们应该使用“瞬态”。 - hcarreras

27

扩展Joe的回答,以允许区分构建和创建:

factory :tx_link do
  units "9.99"

  factory :link_red_to_sub do
    ignore do
      sub 0
      red 0
    end
    units { red }

    giver { build(:transaction, units: sub) }
    taker { build(:redemption, units: red) }

    after(:create) do |link_red_to_sub|
      link_red_to_sub.giver.save!
      link_red_to_sub.taker.save!
    end
  end
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接