概要
原著者の許諾を得て翻訳・公開いたします。
- 英語記事: Learn how to rescue from errors in a Ruby on Rails controller
- 原文公開日: 2018/02/14
- 著者: Paweł Dąbrowsk
Rails tips: コントローラでrescueする方法(翻訳)
Railsのコントローラでエラーをrescue
しなければならないことがあります。クエリをかけたがデータベースにレコードがない場合にraise
される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_method
は、エラー時にしょぼいデフォルトのエラーページではなくもっとましなページを表示したい場合にとても便利です。
お知らせ: RSpec & TDDの電子書籍を無料でダウンロード
もっと稼ぎたい方や会社をさらに発展させたい方へ: テスティングのスキルの重要性にお気づきでしょうか?テストを正しく書き始めることが、唯一のファーストステップです。無料でダウンロードいただける私の書籍『RSpec & Test Driven Developmentの無料ebook』をどうぞお役立てください。