【Rails】FactoryBotをcreateしようとしたらErrorが吐き出されたので調べてみた


RSpecを書いたところ、FactoryBotからuserをcreateするところでエラーが発生してしまうので、原因を調べてみた。

事象

spec/factories/user.rb
FactoryBot.define do
  factory :user do
    name { "テストユーザー" }
    email { "[email protected]" }
    password { "12345678" }
  end
end
user_spec.rb
require 'rails_helper'

RSpec.describe User, type: :model do
  let(:user) { user :user }

  describe "バリデーション" do

    it "nameが空だとinvalid" do
      user.name = ""
      expect(user).not_to be_valid
    end
  end
end

rspecを実行したところ、エラーが発生。
ちなみに今回、Userモデルのvalidatesは:name, presence: trueだけとする。

Failures:

  1) User バリデーション nameが空だとinvalid
     Failure/Error: let(:user) { create :user }

     ActionView::Template::Error:
       Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
     # ./spec/models/client_spec.rb:4:in `block (2 levels) in <top (required)>'
     # ./spec/models/client_spec.rb:9:in `block (3 levels) in <top (required)>'
     # ------------------
     # --- Caused by: ---
     # ArgumentError:
     #   Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
     #   ./spec/models/client_spec.rb:4:in `block (2 levels) in <top (required)>'

Finished in 0.52519 seconds (files took 2.18 seconds to load)
1 example, 1 failure

何やらMissing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true というエラーが吐き出されている。

結論

今回はdeviseを使っているのだが、メール認証機能のconfirmableを有効にしている。

user.rb
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable,
         :confirmable

メール認証機能とは→アカウント新規作成時に登録したアドレスにメールが送られ、確認用リンクをクリックするとログイン画面からログイン可能となる。
このリンクをクリックしたタイミングで、Userのconfirmed_atカラムにその時刻がsaveされる。
どうやらconfirmableが有効の場合、このconfirmed_atがpresentかnilかを見分けて、そのユーザーがログイン可/不可を条件分けしているらしい。
(詳細までは調べられてません)

従って、FactoryBotのファイルにconfirmed_atを書き加えると

spec/factories/user.rb
FactoryBot.define do
  factory :user do
    name { "テストユーザー" }
    email { "[email protected]" }
    password { "12345678" }
    confirmed_at { Date.today }
  end
end
.

Finished in 0.2486 seconds (files took 4.21 seconds to load)
1 example, 0 failures

無事、rspecが通りました。