FactoryGirlでfactory定義のブロックでデフォルトのアソシエーションを書くとその都度関連先のレコードが作成される
FactoryGirlでassociationを使うとき、
factory :item_one, class: Item do name 'first' association :user, factory: :user_one memo 'memo' category_id 1 end
のようにassociationの部分の列を書くと、アソシエーションが含まれているfactoryを使ってレコードを作成する度、 この場合は、item_oneのfactoryでcreateする度、user_oneのfactoryから出来るレコードも作成されます。
それだけだと、これでいいのですが、以下のように、 user_oneのfactoryで作成したレコードに複数のitemのレコードをひもづけたい場合はやや困ります。
FactoryGirl.define do factory :item_one, class: Item do name 'first' association :user, factory: :user_one memo 'memo' category_id 1 end factory :item_two, class: Item do name 'second' association :user, factory: :user_one memo 'memomemo' category_id 1 end end
レコードが生成されるのがいやなら、strategy: :buildの指定を使えばいいのでは、
感あったのですが、:item_oneと:item_twoのfactoryから作ったレコードには
同じusersのレコードのidを持っていて欲しかったのです。
データベースにusersのレコードが1件だけ保存されており、
その保存されたレコードのidをitemのレコードが持っていてほしかったので、
strategy: :buildは使いたくなかったのです。
こういうとき、どう綺麗に書いたら綺麗なのか分からなかったので、とりあえず、手で書いたのを投下します。
def setup @user_one = create(:user_one) @item_one = create(:item_one, user: @user_one) create(:item_two, user: @user_one) create(:item_three, user: @user_two) end
fixturesは当然と言えば当然なのですが
のように書いても新しくレコードが作成されるわけじゃないので、少しびっくりしました。
以下、動作確認用コードを置いてきます。
FactoryGirl.define do factory :item_one, class: Item do name 'first' association :user, factory: :user_one memo 'memo' category_id 1 end factory :item_two, class: Item do name 'second' association :user, factory: :user_one memo 'memomemo' category_id 1 end factory :item_three, class: Item do name 'third' association :user, factory: :user_two memo 'memomemomemo' category_id 1 end end
FactoryGirl.define do factory :user_one, class: User do first_name '太朗' last_name '田中' age 20 postal_code '111-1111' address_1 '東京都どこか区' address_2 'そのへん町1-2-3' address_3 'アパート適当456' end factory :user_two, class: User do first_name '次郎' last_name '佐藤' age 30 postal_code '222-2222' address_1 '何とか県いずこ市' address_2 'あのへん町3-2-1' address_3 '' end end
def setup @user_one = create(:user_one) puts "after @user_one = create(:user_one) User.count #{User.count}" create(:user_two) puts "after create(:user_two) User.count #{User.count}" @item_one = create(:item_one) puts "after @item_one = create(:item_one) User.count #{User.count}" create(:item_two) puts "after create(:item_two) User.count #{User.count}" create(:item_three) puts "after create(:item_three) User.count #{User.count}" end
def setup @user_one = create(:user_one) puts "after @user_one = create(:user_one) User.count #{User.count}" create(:user_two) puts "after create(:user_two) User.count #{User.count}" @item_one = create(:item_one, user: @user_one) puts "after @item_one = create(:item_one, user: @user_one) User.count #{User.count}" create(:item_two, user: @user_one) puts "after create(:item_two, user: @user_one) User.count #{User.count}" create(:item_three, user: @user_two) puts "after create(:item_three, user: @user_two) User.count #{User.count}" end