0
0

Deviseの内部挙動とActiveRecord::RecordNotFound の解消について

Last updated at Posted at 2024-02-27

はじめに

RailsアプリケーションにおいてDeviseを用いたユーザー認証機能のカスタマイズ中にActiveRecord::RecordNotFound - Couldn't find Staff without an ID:というエラーメッセージが発生しました。この記事では、このエラーがなぜ発生したのか、そしてどのようにして解決に至ったのかを共有します。

エラーの内容

ユーザー情報の更新フォームを送信した際に、以下のエラーメッセージが表示されました。

ActiveRecord::RecordNotFound - Couldn't find Staff without an ID:
  app/controllers/staffs/registrations_controller.rb:46:in `set_staff'
Started GET "/staffs/edit?id=2" for ::1 at 2024-02-28 00:00:38 +0900
Processing by Staffs::RegistrationsController#edit as HTML
  Parameters: {"id"=>"2"}
  Staff Load (1.8ms)  SELECT "staffs".* FROM "staffs" WHERE "staffs"."id" = $1 ORDER BY "staffs"."id" ASC LIMIT $2  [["id", 2], ["LIMIT", 1]]
  Staff Load (1.9ms)  SELECT "staffs".* FROM "staffs" WHERE "staffs"."id" = $1 LIMIT $2  [["id", 2], ["LIMIT", 1]]
  ↳ app/controllers/staffs/registrations_controller.rb:46:in `set_staff'

このメッセージは、一般的には、IDを指定せずにStaffオブジェクトを検索しようとしたときに発生します。
しかし、ログを確認するとidはパラメータとしてきちんと送信されています。問題はset_staffメソッド内で発生しているようですが、そのメソッドが正しくIDを使用してStaffオブジェクトを検索していることがログからも確認できます。

原因と経緯

エラーの根本的な原因は、set_staffメソッドとそのbefore_actionコールバックがDeviseのコントローラー内に記述されてDeviseの内部処理と競合していたことにありました。これらのコードは、@staffオブジェクトを設定するために意図されていましたが、編集画面で@staff変数が適切にセットされていない状況を引き起こしていました。

解決策

set_staffメソッドとそれを呼び出すbefore_actionコールバックの削除が解決策でした。これらのコード行を削除することで、Deviseのデフォルトの挙動に任せることができ、エラーは解消されました。

registrations_controller.rb
before_action :set_staff, only: %i(edit update destroy)
registrations_controller.rb
def set_staff
  @staff = Staff.find(params[:id])
end

なお、もしset_staffを使用したい場合は

registrations_controller.rb
def set_staff
  @staff = Staff.find(resource.id)
end

とすると使用できます。

まとめ

この問題は、Deviseのフレームワークの内部動作に十分な理解がない状態で余計なコードを追加してしまった結果生じました。Deviseのような複雑なライブラリを使用する際には、そのデフォルトの動作を理解し、必要なカスタマイズのみを慎重に行うことが重要です。

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