先日、before_actionの実行順が原因で開発のアラートが大量発生したので、回顧録として記載していきます。
自分が作業したタスク
下記のようなbefore_action(特定の権限のみに画面を表示させる)メソッドを追加した。
before_action :prevent_invalid_user # 不正なアクセスユーザーを防ぐメソッド
+ before_action :redirect_specific_supervisor_page unless current_company.uncontracted_company?# 特定の権限のみに画面を表示させるメソッド(未契約企業は発火させない条件付き)
発生した事象
上記の追加したタスクによって、prevent_invalid_userでリダイレクトされるはずの処理が実行されず500エラー画面発生。しかもセッション切れるたびに発火するメソッドなため、高頻度でアラートが出る。
ユーザー画面:画面上でセッション切れた → 画面更新 → 500エラー発生
発生した原因
ここからが本題です。
まず、もともと実装されていたprevent_invalid_userというのはapplication.rbで定義されており、初期段階で呼び出されるメソッドです。
本来の呼び出される想定の順番
①prevent_invalid_userの定義先
controller.rb
before_action :prevent_invalid_user # 不正なアクセスユーザーを防ぐメソッド
②prevent_invalid_userの定義元
application.rb
def prevent_invalid_user
return unless current_company.nil?
render "auth/login_user.html" # ログインユーザー画面
end
③ここでcurrent_companyがnilとなり、ログイン画面へリダイレクト
④終了
実際の呼び出される順番
①追加したメソッドが呼ばれる
before_action :redirect_specific_supervisor_page unless current_company.uncontracted_company?
②current_companyがnilになるので500エラーが発生
③バグ発生!!!
原因
親の継承元のapplication controllerの実行順番によって、不正アクセスを防ぐメソッドに到達するまでに500エラーが発生。結果バグが発生してしまった。本来は追加したメソッドが優先的に実行されるベキだったので、下記に修正する必要があった。
prepend_before_action :before_action :prevent_invalid_user
こうすることでbefore_actionよりも先に実行されることで実行順序を入れ替えることができた。めでたしめでたし。
参考文献
