kakudooo docs

FactoryBotで異なる属性を持つ複数のレコードを作成する方法

テストを書いていてレコードを一度に複数用意してかつ、呼び出し時にそれぞれのレコードの属性を異なるものにしたいことが時々ある。 FactoryBotでそれを実現する方法についてまとめておく。

build_listやcreate_listにblockを渡して保存する

create_listで複数のレコードを作成しつつ、ブロックで任意の属性に異なる値を設定することができる。 インスタンスを上書きたい場合はsaveメソッドなどを使い、再度更新する必要があるので注意。

twenty_somethings = create_list(:user, 10) do |user, i|
  user.date_of_birth = (20 + i).years.ago
  user.save!
end

また、上記のようにcreate_listで一度保存したインスタンスに対して再度更新処理をかけると2n回クエリが発行されてしまう。build_listを使用することでクエリの発行回数を抑えることができる

twenty_somethings = build_list(:user, 10) do |user, i|
  user.date_of_birth = (20 + i).years.ago
  user.save!
end

参考

個々の属性を含む配列をループで回して、createする

あらかじめ対象の属性値を含む配列(データセット)を定義しておき、mapメソッドのブロック内でcreateすることで任意の属性に異なる値を設定することができる。

[ { name: '田中', role: '管理者' }, { name: '山田', role: '編集者' }, { name: '渡辺', status: '閲覧者' } ].map do |restaurant_name|
	create(:user, name: attributes[:name], status: attributes[:status])
end

使い分け

のように使い分ける。

参考

xxx_listメソッドの内部実装

FactoryBotの内部実装を確認してみた時にメモしたリンク集。