Has_many 'Bar'というモデルFoo
があります。これらのオブジェクトごとにfactory_girlファクトリがあります。 BarのファクトリーはFooに関連しています。バーを作成するときにFooをインスタンス化します。
バーを含むFooを作成するファクトリーが欲しいのですが。理想的には、このバーは:barファクトリーを通じて作成され、Fooの作成に使用されたビルド戦略(create/build)を尊重します。
:barファクトリーを呼び出して、新しいBarからFoo参照を取得できることはわかっています。これは避けたいです。私のテストケースでは、重要なオブジェクトはFooです。 Barファクトリーを呼び出すことは少し遠回りに思えます。また、複数のバーを持つFooの必要性もわかります。
これはfactory_girlで可能ですか?この関係を親でどのように定義しますか?
Factory.after_ hooks
は、これを成功させる唯一の方法のようです。コードを複製せずにビルド戦略を維持する方法を見つけました。
Factory.define :foo do |f|
f.name "A Foo"
f.after(:build) { |foo|
foo.bars << Factory.build(:bar, :foo => foo)
}
f.after(:create) { |foo|
foo.bars.each { |bar| bar.save! }
}
end
documentation は、after_build
ビルド戦略が使用されている場合、after_create
の前に:create
が呼び出されることを示しています。 :build
を使用すると、after_build
のみが呼び出され、誰もが満足します。
抽象化された一般的に適用可能なバージョン この要点 も作成して、物事を乾いた状態に保ちます。
association
メソッドは両方の方法で使用できます。
Factory.define :foo do |f|
# ...
f.association :bar
end
それが機能しない場合は、コールバックを使用して手動で関連付けることができます。これが私のアプリの例です:
Factory.define :live_raid do |raid|
end
Factory.define :live_raid_with_attendee, :parent => :live_raid do |raid|
raid.after_create { |r| Factory(:live_attendee, :live_raid => r) }
end
FactoryGirl 4.3.0は、親オブジェクトでbuild
を呼び出すときに、関連付けでsave!
を呼び出していますが、これは正しい動作を意図したものではないと考えています。
FactoryGirlコードを調べた後、strategy: :build
をファクトリの関連付け定義に追加すると、save!
を呼び出さずに関連付けが作成されるようになりました。
FactoryGirlに:method => :build
オプションを関連付けで使用すると、関連付けられたオブジェクトを作成するのではなく作成します。
factory_girl-4.5.0
を使用して、親オブジェクトファクトリにn個の子オブジェクトを作成します
FactoryGirl.define do
factory :foo do
name "test"
after(:build) do |instance|
n.times { instance.bars << FactoryGirl.create(:bar) }
end
end
end