概要
原著者の許諾を得て翻訳・公開いたします。
- 英語記事: Learn how to rescue from errors in a Ruby on Rails controller
- 原文公開日: 2018/02/14
- 著者: Paweł Dąbrowsk
Rails tips: rescue_fromでコントローラのエラーをrescueする(翻訳)
Ruby on Railsのコントローラで発生したエラーをrescue
しなければならなくなることがときどきあります。多くの場合、クエリ実行後データベースにレコードが存在していなければActiveRecord::RecordNotFound
例外からのrescue
が必要になるでしょう。
サンプルのコントローラを書いてみましょう。
class UsersController < ApplicationController
def show
@user = User.find(params[:id])
rescue ActiveRecord::RecordNotFound => e
redirect_to :root, alert: 'User not found'
end
def edit
@user = User.find(params[:id])
rescue ActiveRecord::RecordNotFound => e
redirect_to :root, alert: 'User not found'
end
end
このコントローラには2つのメソッドがあり、どちらも同じ例外を同じ方法で扱っています。このコードをもっと再利用するために、ActiveSupport
モジュールのrescue_from
メソッドを使う手があります。
class UsersController < ApplicationController
rescue_from ActiveRecord::RecordNotFound do |exception|
redirect_to :root, alert: 'User not found'
end
def show
@user = User.find(params[:id])
end
def edit
@user = User.find(params[:id])
end
end
before_action
フィルタを用いてshow
メソッドとedit
メソッドをリファクタリングすることもできますが、今回は解説しません。さて、上のようにすることでコントローラが読みやすくなり、同じコードを2回も書かなくてよいようになりました。気持ちいいですね!ブロックの代わりにメソッド名を渡すこともできます。
class UsersController < ApplicationController
rescue_from ActiveRecord::RecordNotFound, with: :redirect_to_homepage
def show
@user = User.find(params[:id])
end
def edit
@user = User.find(params[:id])
end
protected
def redirect_to_homepage
redirect_to :root, alert: 'User not found'
end
end
concernsを使って、1つのメソッドを複数のコントローラで使いまわすことだったできます。この方法が使えるかどうかは、渡された例外をrescue
するのに用いるロジック次第です。rescue_from
は、エラー発生時にユーザーに見栄えのよいエページを表示したいときにとても便利です。このメソッドがなければ、しょぼいデフォルトエラーページが表示されることになるでしょう。
RSpec & TDDの電子書籍を無料でダウンロード
もっと稼ぎたい方や会社をさらに発展させたい方へ: テスティングのスキルの重要性にお気づきでしょうか?テストを正しく書き始めることが、唯一のファーストステップです。無料でダウンロードいただける私の書籍『RSpec & Test Driven Developmentの無料ebook』をどうぞお役立てください。