...

【Rails】Validation failed: 〜 must exist の対処法

Railsの「Validation failed: 〜 must exist」

  どうもおはようポテトです。

先日、Railsで以下のようなエラーに遭遇しました。

ActiveRecord::RecordInvalid (Validation failed: Lost must exist):

 

ということで今回は

「同じようなエラーに遭遇したので解決法を知りたい」

「エラーの原因も知りたい」

という方に向けてこの「Validation failed: (モデル名) must exist」というエラーの対処法をまとめました。

自分の備忘録代わりでもありますが、参考になれば幸いです⸝⸝- ̫ -⸝⸝

ブログ主

早速いってみよう!

Validation failed: (モデル名) must existの解決法

このエラーに対して

ブログ主の場合、このLostというモデルと1対多の関係にあるMatterモデルクラスに以下のように記述することで解決しました。

class Matter < ApplicationRecord
  belongs_to :user
  belongs_to :lost, optional: true #ここを追加
end

 

ということで解決法を簡潔にまとめると…

解決法

モデルクラスの関連付けのメソッドの引数に「optional: true」を記述

次はこの「optional: true」について!

ソロモン

「optional:true」とは何ぞや?

class Lost < ApplicationRecord
  has_many :matters, dependent: :destroy
end
class Matter < ApplicationRecord
  belongs_to :lost, optional: true
end

このようにLostモデルとMatterが1対多の関係にあるとします。

その場合、

Matterテーブルの外部キーであるlost_idというカラムは、自動でnillが禁止になる

よってバリデーションではじかれてしまいエラーになる

というわけです

ブログ主

なるほどね

optional: true」とは

簡潔に説明すると、この「optional: true」は「外部キーがnillであることを許可してくれるオプション」です

belongs_to :lost, optional: true

この「optional: true」を関連付けのメソッドbelongs_toのオプションで記述することによって、

「空でもいいよ」ということになるのでバリデーションにひっからず上手く保存されるということですね。

余談

class MattersController < ApplicationController
  def q1_after
    @matter=Matter.new(user_id:current_user.id, is_solved:false)
    @lesson=Lesson.find_by(name:params[:lesson])
    category=params[:category]
    if @matter.save #lesson_idが空の状態
      redirect_to("/q2/#{@matter.id}/#{@lesson.id}/#{category}")
    else
    flash[:notice]="やり直してください"
    redirect_to("/q1")
    end
  end
end

ブログ主の場合、この6行目のレコードを保存する際に外部キーが空であった(にしていた)ため、今回のエラーにひっかりました。

最後に

以上となります。

まあ本来外部キーをnilのまま保存することの方が珍しい(?)ので、そこまで気をつける必要は無いかもしれませんが、頭の片隅ぐらいには入れておきたいですね。

最後まで読んでいただきありがとうございました!では⸝⸝- ̫ -⸝⸝

参考になったらシェアしよう

コメントを残す

メールアドレスが公開されることはありません。

CAPTCHA