はじめに
deviseの RegistrationsController の editアクションにbefore_action :authenticate_user! を適応したい。
そのまま書いてみるだけではできませんでした。
ちなみに、他のコントローラーでは期待どおりに動作します。
before_action :authenticate_user! とは
特定のアクションを実行する前にユーザーが認証されているかを確認するためのDeviseのメソッドのこと。
このメソッドを使うと、ユーザーがログインしていない場合はログインページにリダイレクトされます。
下記がうまくいかない。
app/controllers/users/registrations_controller.rb
module Users
class RegistrationsController < Devise::RegistrationsController
before_action :authenticate_user!, only: [edit]
結論
下記の二つの方法でうまくいきました。
app/controllers/users/registrations_controller.rb
module Users
class RegistrationsController < Devise::RegistrationsController
prepend_before_action :authenticate_scope!, only: [edit]
または
app/controllers/users/registrations_controller.rb
module Users
class RegistrationsController < Devise::RegistrationsController
before_action ->{ authenticate_user!(force: true) }, only: [edit]
原因
deviseのコントローラと競合してるっぽい。
app/controllers/devise/registrations_controller.rb
class Devise::RegistrationsController < DeviseController
prepend_before_action :require_no_authentication, only: [:new, :create, :cancel]
prepend_before_action :authenticate_scope!, only: [:edit, :update, :destroy]
prepend_before_action :set_minimum_password_length, only: [:new, :edit]
修正後のコードでオーバーライドした形になります。
prepend_before_action は、指定したメソッドを before_action よりも前に実行されます。
そのため、devise の prepend_before_action が優先され、 before_action :authenticate_user! 動かなかったのだと思います。
参考記事