【FactoryBot】associationの使い方


前提条件

以下を前提条件に話を進めていきます。
①以下のテーブルが存在する。
※Railsで自動で生成されるカラムは一部省略しています。

users :ユーザーテーブル
posts:ユーザーのつぶやきを保存するテーブル
goods:いいね機能のテーブル

②Railsの関連が定義済みであること。

associationとは

関連するデータを一緒に作成してくれるメソッド

例えばpostsテーブルのテストデータを作成する時に、必ずusersのデータが必要になる。
この時associationを使わない方法でテストデータを作成すると以下のようになる。

post_spec.rb
# モデルテスト
RSpec.describe Post, type: :model do
  let(:user) { FactoryBot.create(:user) }
  let(:post) { FactoryBot.create(:post, user_id: user.id) }
end

このようにuserとpostの両方のテストコードを記述しなければならない。
二つだけならまだいいが、さらに関連するテーブルが増えていくと記述するのが大変。
これを解決するのがassociationメソッド。

使い方

①factoryにassociationを記述

posts.rb
# ポストファクトリー
FactoryBot.define do
  factory :post do
    association :user
  # factory名が違う場合以下のように記述する
  # association :user, factory: :tom
  end
end

②specにてデータを作成する

post_spec.rb
RSpec.describe Post, type: :model do
  let(:post) { FactoryBot.create(:post) }
end

これでpostデータ作成と同時にuserデータも作成される。
さらにpostのuser_idも自動でidが入る。

associationで作成するデータが被ってしまう場合

例えばgoodデータを作成する時、以下のようにするとuserデータが二つ作られてしまう。

good.rb
FactoryBot.define do
  factory :good do
    # postには「association :user」が宣言されているため
    # userのデータが二つ作られることになる。
    association :post
    association :user
  end
end

解決方法

これを解決するにはpostで作成されたuserを使えばいい。

good.rb
FactoryBot.define do
  factory :good do
    association :post
    user { post.user }
  end
end

まとめ

associationとは関連するデータを同時に作成するメソッド
これを使うとコードがスッキリする

ここまでご覧いただきありがとうございました。