🐡

ActiveRecord::RecordInvalid: Validation failed: 〇〇 must exist解決法

2024/01/10に公開

概要

RailsでRSpecを実行する際に、なかなかテストが通らずに苦戦しました。
特に1番苦しめたのは

ActiveRecord::RecordInvalid:        Validation failed: 〇〇 must exist

です。しかし記事を調べてもなかなかうまくいかずに大苦戦した。
その時のことを書いていきます。

参考にしたけど解決できなかった記事(この記事が悪い訳ではない)

こちらの記事を参考にしたのですが、解決には至らなかったです。
この記事が悪いとかそういう話ではなく
人によって環境が様々だからです。下の記事にも書いてあります

https://zenn.dev/kingdom0927/articles/bab454cc047960

なので自分の場合で見ていきます

そもそも何のエラー

このエラーは、〇〇が存在していないので、エラーになっています。
本来なら〇〇が存在していなければいけないはずが存在していないことが原因です。

今回はUserです。

ActiveRecord::RecordInvalid:        Validation failed: User must exist

状況説明

Railsで日報一覧のAPIを作ってしました。APIができたらRSpecでテストをすることになっていました。しかし、以下の問題が出てきました。

curlでサーバーは動くけど、RSpecでテストが通らない

⚫︎補足
curlは、コマンドラインツールで、
URLを使用してデータを転送するためのクライアント側のプログラム
です。
"Client for URLs"(URLのためのクライアント)からきています。
主に、HTTPやHTTPSを使用したデータの送受信に使われ、
APIの現場で採用されるみたいです。
APIだとPostmanで挙動確認の現場もあったりします。

最初はmodelかコントローラーでエラーが出ているかと思ったら、
サーバーでは動くので問題はRSpecの書き方に問題がありました。

curlでサーバーは動くからmodelに問題はなくてRSpecに問題がありました。

require 'rails_helper'

RSpec.describe Api::V1::Web::Users::DailyReportsController do
  let(:user) { User.first }
  raise User.first.inspect #デバックするとUser.firstがnilだった
  let!(:daily_report) { create(:daily_report,user:)}
#中略

デバックしたらUser.firstがnilだったので、原因はここでした。
Userデータを作成していなかったのです。

他にもFactoryBotを入れていたのでfactoriesの中のusersを確認したら
問題もなく、railskonso-rudeUser.allで調べてもデータはちゃんと取れていました。

こうしてエラーを特定できました。

require 'rails_helper'

RSpec.describe Api::V1::Web::Users::DailyReportsController do
  let(:user) { create(:user) }#ユーザーデータ作成
  raise User.first.inspect #デバックするとUser.firstがnilだった
  let!(:daily_report) { create(:daily_report,user:)}
#中略

これでデバックをするとデータが取れていることがわかりました。
コントローラーでUser.firstでデータを取っていたので、
なかなかlet(:user) { create(:user) }と書くことが思い浮かびませんでしたが、
エラーの場所が特定できたので、なんとか解決できました。

letとか何のこっちゃと思ったら読んでみてください。

https://qiita.com/Hashimoto-Noriaki/items/34a21de8a578b52ecb51

Discussion