1
0

More than 3 years have passed since last update.

FactoryBotでの外部参照キーの記述方法

Last updated at Posted at 2020-12-27

はじめに

Railsでテストコードを記述していたところ、必要事項を全て埋めても、外部参照したカラムの記述に関するエラーが出たので、FactoryBotでの外部参照キーの記述方法についてまとめました。

前提条件

下記のER図のようなUserモデルとArticleモデルにおいて、Articleモデルのuser_idが外部参照している場合を考えます。また、下記のようにUserのFactoryBotは定義済みとします。
ER.png

user.rb
# UserのFactoryBot
FactoryBot.define do
  factory :user do
    nickname               {Faker::Name.name}
    email                  {Faker::Internet.email}
    password               {Faker::Internet.password}
    password_confirmation  {password}
    last_name              {"投稿"}
    first_name             {"太郎"}
  end
end

実行するテストコード

article_spec.rb
# Articleで実行するテストコード
require 'rails_helper'

describe Article do
  before do
    @article = FactoryBot.build(:article)
  end

  describe '記事新規投稿' do
    context '新規投稿がうまくいく時' do
      it '必要事項が全て存在すれば登録できる' do
        expect(@article).to be_valid
      end
    end
    context '新規投稿がうまくいかない時' do
      it 'titleが空だと登録できない' do
        @article.title = ""
        @article.valid?
        expect(@article.errors.full_messages).to include("Title can't be blank")
      end
    end
  end
end

上記のように、Articleモデルの単体テスト実行の場合を考えます。今回は、簡単のために、正常系として必要事項が全て記述されたとき、異常系としてtitleカラムが空の場合のみを考えます。

エラーになったコード

article.rb
# ArticleのFactoryBot
FactoryBot.define do
  factory :article do
    title            {"あいうえお"}
    prefecture_id    {Faker::Number.within(range: 1..10)}
    distance         {Faker::Number.within(range: 10..500)}
    content          {"あいうえおかきくけこ"}
    user_id          {1}
  end
end

最初は、上記のarticle.rbでArticleのFactoryBotを定義し、article_spec.rbのテストを実行しましたが、it '必要事項が全て存在すれば登録できる'の部分で'User must exist'のエラーが生じました。これにより、article_rbのuser_id {1} という記述だけでは、外部参照出来ていないことがわかります。

解決策1

article_spec.rb
# ArticleのFactoryBot
FactoryBot.define do
  factory :article do
    title            {"あいうえお"}
    prefecture_id    {Faker::Number.within(range: 2..48)}
    distance         {Faker::Number.within(range: 10..500)}
    content          {"あいうえおかきくけこ"}
    user             {FactoryBot.create(:user)}
  end
end

user_id {1} としていた部分をUserのFactoryBotで生成したインスタンスに変更しました。これにより、articlesテーブルで外部参照可能になり、無事article_spec.rbのテストコードが正しく実行されました。

解決策2

article_spec.rb
# ArticleのFactoryBot
FactoryBot.define do
  factory :article do
    title            {"あいうえお"}
    prefecture_id    {Faker::Number.within(range: 2..48)}
    distance         {Faker::Number.within(range: 10..500)}
    content          {"あいうえおかきくけこ"}
    association      :user
  end
end

次に、user_id {1} としていた部分をassociation :userという記述に変更しました。この記述でも、article_spec.rbのテストコードが正しく実行されました。

まとめ

FactoryBotで外部参照キーを記述する際は、user_id {1} などのように直接数字を記述するだけでは正しく外部参照できず、解決策①②のような記述が必要なことを学びました。

1
0
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
1
0