🚒
rescue_fromに助けてもらうには
状況
- 当初コード
def set_article
@article = Article.find(params[:id])
rescue ActiveRecord::RecordNotFound
redirect_to articles_path, flash: { error: '記事が見つかりません' }
end
- 上記コードに対して、
「"rescue_from ActiveRecord::RecordNotFound, with: :handle_record_not_found" とかで
"ActiveRecord::RecordNotFound" を親元のクラスにハンドリングし継承すべき」とアドバイスをいただきました。 - これを機にrails apiで発生した例外をメソッド毎ではなく、定義と継承によって一括で処理することを学んだので、記載したいと思います。
学び
- 例外が発生したらその親元のクラスのbase_controller.rb に
= set_articleメソッドをArticlesControllerに残しつつ、ActiveRecord::RecordNotFoundの例外をBaseControllerで共通処理としてハンドリングする。
rescue_from ActiveRecord::RecordNotFound, with: :handle_record_not_found
private
def handle_record_not_found
ここに共通化した処理をかく
end
具体例
1.BaseControllerに共通の例外処理を追加 :
- rescue_from ActiveRecord::RecordNotFoundを使用して、例外が発生したときに共通の処理を実施
class BaseController < ApplicationController
rescue_from ActiveRecord::RecordNotFound, with: :handle_record_not_found
private
def handle_record_not_found
redirect_to top_path, flash: { error: 'この操作は実行できません' }
end
end
2.set_articleメソッドの修正:
- set_articleメソッドからrescueブロックを削除し、例外はBaseControllerで処理されるように
class ArticlesController < BaseController
before_action :set_article, only: [:edit, :update]
private
def set_article
@article = Article.find(params[:id])
end
end
所見
- set_articleメソッドをArticlesControllerに残しつつ、
BaseControllerを継承するすべてのコントローラーで例外処理を共通化することができるように
= コードの重複を避けることができる。 - わかりやすい記事を記載されている方がいらっしゃりましたので、参考に載せさせていただきます。
Discussion