42
42

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-07-07

前提として

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文みたいでちょっと読みやすいような

42
42
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
42
42

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?