FactoryGirlで多対多の関連データを一緒に生成する
以下の記事を参考にさせていただきました。
FactoryGirl で多対多のアソシエーションをつくる
http://blog.inouetakuya.info/entry/2013/12/28/205008
FactoryGirlsのアソシエーションのとこは以下から。
http://www.rubydoc.info/gems/factory_girl/file/GETTING_STARTED.md#Associations
factory_girl で最低限知っておきたい4つの使い方(@sasata299さん)
http://blog.livedoor.jp/sasata299/archives/51931175.html
手順
ここの記事で非常にわかりやすくまとめていただいていました。
- まず1個目のモデル(Category)のfactoryを普通に定義する。
- 次に、2個目のモデル(Book)を定義するfactoryブロックの中でafter()を使う。
- after(:create)に渡すブロックのなかでアソシエーション用のオブジェクトを作成して、2つのオブジェクトのインスタンスを引数に取らせる
Userがbuildまたはcreateされたときに、それに関連するDetailsも生成されるようにしたいという想定で。
spec/factories/users.rb
を以下のようにすればok!
FactoryGirl.define do factory :user do sequence(:email) { |n| "ex#{n}@ex.com" } sequence(:password) { |n| "password#{n}" } # createされたあとに関連モデルデータもcreateする after(:create) do |user| create(:user_details, user: user, detail: create(:detail)) end end end
これでuser_details
を作成するときにリファレンスでuser
とdetail
も関連付けされたデータを生成できる。
after(:create)
かafter(:build)
かは、用途によって使い分けるのがいいと思う。自分はcreate
のときにはDBに保存するってところから確実に結びついたデータがほしいということで、build
のときには、関連データはその場で作った他のデータをくっつけたりする場面で必要なときに使ったりできるようにした方が便利だなと思ってafter(:create)
にした。