rescue_fromなどを用いたエラーハンドリングをリファクタリング
【結論】
・例外をキャッチする方法として、begin~rescueメソッドがあるが、メソッド全体を指定する場合、beginは省略可能
・rescue_fromを利用すれば、指定したコントローラー全体の例外をキャッチする事が可能
【目次】
【本題】
エラーハンドリングのリファクタリング
404や500エラーが発生した際に、任意のエラーページを表示させるには、コントローラーで発生する例外をキャッチする必要があります。
例外をキャッチする一般的な方法として、begin~rescue
を使用する方法があります。
class PostsController < ApplicationController def show begin @post = current_user.post.find(params[:id]) rescue ActiveRecord::RecordNotFound => e render 'errors/error_404', status: :not_found end def edit begin @post = current_user.post.find(params[:id]) rescue ActiveRecord::RecordNotFound => e render 'errors/error_404', status: :not_found end end
但し、これだと何点か冗長な部分があるので、リファクタリングを行っていきます。
beginの省略
まず、例外を検知する範囲をメソッド全体に指定するのであれば、begin
は省略可能です。
class PostsController < ApplicationController def show @post = current_user.post.find(params[:id]) rescue ActiveRecord::RecordNotFound => e render 'errors/error_404', status: :not_found end def edit @post = current_user.post.find(params[:id]) rescue ActiveRecord::RecordNotFound => e render 'errors/error_404', status: :not_found end end
rescue_fromの活用
rescue ActiveRecord::RecordNotFound => e
という記述がDRYでは無いので、共通化させます。
その際に利用するのが、rescue_from
です。
rescue_from
によって、コントローラー全体の例外をキャッチする事が可能になります。
class PostsController < ApplicationController rescue_from ActiveRecord::RecordNotFound do |exception| render 'errors/error_404', status: :not_found end def show @post = current_user.post.find(params[:id]) end def edit @post = current_user.post.find(params[:id]) end end
これにより、各メソッドの見通しが非常に良くなりました。
最後に、今回のテーマと関係無いですが、@post
を生成する部分もbefore_action
で共通化します。
class PostsController < ApplicationController rescue_from ActiveRecord::RecordNotFound do |exception| render 'errors/error_404', status: :not_found end before_action :set_post def show end def edit end private def set_post @post = current_user.posts.find(params[:id]) end end
これで完成です。
参考情報
https://ruby-rails.hatenadiary.com/entry/20141111/1415707101
[Ruby] 例外処理を実装する時のrescue書き方3パターン - Qiita
Rails tips: rescue_fromでコントローラのエラーをrescueする(翻訳)|TechRacho by BPS株式会社