ActiveRecord::RecordNotFound (Couldn’t find xxx without an ID) の原因と対処法【Ruby on Rails 初心者向け】

Ruby on Rails

ActiveRecord::RecordNotFound (Couldn’t find xxx without an ID) というエラーがでて修正できません。

どんなふうに解決していけばいいでしょうか・・・

そんな疑問にお答えします。

このエラーは Ruby on Rails のモデルに起因するエラーです。

エラーメッセージを見て解決できていない場合、モデルの使い方に不明点があるのではないでしょうか。

この記事を読んで実際のエラーに対処できるようになればRailsのコーディング力が一段と向上しますよ!

原因: find(nil) で検索しようとしている

エラーメッセージが ActiveRecord::RecordNotFound (Couldn’t find xxx without an ID) の場合、

モデルのクラス.find(nil)

のように find メソッドに nil が渡されている状態です。

直接 nil と書くことは無いと思うので、例えば

Book.find(params[:book_id])

のようなコードがあるときに params[:book_id] が nil であるような場合に発生します。

対処法

find メソッドに nil を渡すとエラーとなるわけなので、nil ではない値を渡すように修正すれば治ります。

もし、nilを渡す可能性がある場合は find メソッドは使えないので、似た機能を持つ find_by メソッドで置き換えることを検討する必要があります。

よくある間違いと対処法

パラメータ名を間違えている

find メソッドを使う場合、

def show
  @book = Book.find(params[:book_id])
end

のように params を使ってパラメータから id を取得し、それを引数にしている場面が多いと思います。

上記の例では params[:book_id] としているので、book_id というパラメータ名で id が送られてくることを想定しています。

このときもしパラメータに book_id がなければ params[:book_id] は nil となり、結果として Book.find(nil) を実行していることになります。

こうして ActiveRecord::RecordNotFound (Couldn’t find xxx without an ID) が発生します。

これを修正するにはエラー画面に Request セクションの Parameters: のところを確認してみましょう。

上記のように book_id パラメータではなく id パラメータだったことに気づくことができます。

これは一例であり、仕様によってはそもそも book_id パラメータが送られていないこと自体が問題であったりするので、各自の仕様と照らし合わせて検討することが大切です。

find と find_by を取り違えている

Rails 初心者にありがちな勘違いは find メソッドと find_by メソッドの取り違いです。

違いを確認しておきましょう。

  • find(数字) で id = 数字のレコードを取得する
  • find_by(ハッシュ)でハッシュを条件で検索し、その1件目を取得する

find_by(id: 数字) とすると id = 数字のレコードを取得することになり、find(数字) と同じに見えます。

しかし、find メソッドと find_by メソッドは見つからなかったときの挙動に差があります。

見つからなかったときの動作は以下のように定義されています。

  • find メソッド → エラーになる
  • find_by メソッド → nil を返す

このエラーとなる場合に発生するのがActiveRecord::RecordNotFoundです。

この挙動の差によって find メソッドと find_by メソッドを使い分ける必要があります。

つまり

  • 指定した id が存在しないことが想定されない場合 → find メソッドを使う
  • 指定した id が存在しないことが想定される場合 → find_by メソッドを使う

このように似ているけど動作が異なるメソッドについてもしっかりと理解しておくと不要なエラーを防ぐことができます。

まとめ

ActiveRecord::RecordNotFound (Couldn’t find xxx without an ID) の原因と対処法について解説しました。

find メソッドの使い方と、その引数へ渡しているインスタンスがしっかりと把握できれば修正できますのでがんばりましょう!

その他の Rails エラー関連記事はこちら

タイトルとURLをコピーしました