Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

FactoryBotで1対1や1対nのモデルを複数作る

More than 1 year has passed since last update.

前提として

Rspecで1対1の関係のモデルのテストデータを複数作りたい

うーんってなったので忘れないようついでに他のパターンも一緒にまとめました

  • モデルを複数作る
  • 1対1のデータを1つ作る
  • 1対nのデータを1つ作る
  • 1対1のデータを複数作る ←今回やりたくて悩んだのはここ
  • 1対nのデータを複数作る

ここで例として扱うモデルは
1対1も含めたいのでよくある1対nの親モデルUserと子モデルPostにしました

まず、FactoryBotでモデルを複数作成するには

create_listを使います

FactoryBot.create_list(:post, 3)

Postモデルを3つ作れる

1対1のデータを作る

パターンA

FactoryBot.create(:post, user: FactoryBot.create(:user))

パターンB

user = FactoryBot.create(:user)
FactoryBot.create(:post, user: user)

パターンC

FactoryBot.create(:user) do |u|
  FactoryBot.create(:post, user: u)
end

1対nのデータを作る

パターンA

user = FactoryBot.create(:user)
FactoryBot.create_list(:post, 3, user: user) 

パターンB

FactoryBot.create_list(:post, 3, user: FactoryBot.create(:user)) 

User : Post = 1 : 3のデータを作ってるんですが
ぱっと見、Post : User = 1 : 1のデータが3つできるようにも見えません?
自分はそう見えて「1対1のデータを複数作る」にはどうすれば、と悩みました

でもまぁよくよく考えてみると妥当な挙動だと思います

1対1のデータを複数作る

これこれ これがやりたかった

FactoryBot.create_list(:user, 3) do |u| 
  FactoryBot.create(:post, user: u)
end

1対nのデータを複数作る

1対1のデータを複数作った時点で目的達成なのですが
せっかくなのでついでに1対nについても考えてみました

パターンA(力技)

3.times do
  FactoryBot.create(:user) do
    FactoryBot.create_list(:post, 3, user: user)
  end
end

これでもいいんですがRubocopにシバかれたので考え直してパターンBにたどり着きました

パターンB

FactoryBot.create_list(:user, 3) do |u| 
  FactoryBot.create_list(:post, 3, user: u) 
end

これで
User : Post = 1 : 3のデータが3つ作成されます

ブロック使うことでイメージとしてはcreate_listがfor文みたいでちょっと読みやすいような

rh_taro
timee
日本の労働力の減少を若者の働き方改革で解決します。好きな時に好きなだけ働けるプラットフォームタイミーを作り、人々が好きなことをできる世界を実現します。
https://timee.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away