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
concernを使えば、1つのメソッドを複数のコントローラで使い回すことも可能です。これは、受け取った例外からrescue
するロジックに依存します。rescue_from
は、エラー時にデフォルトの退屈なエラーページではなく、もっとましなページを表示したい場合にとても便利です。
お知らせ: RSpec & TDDの電子書籍を無料でダウンロード
もっと稼ぎたい方や会社をさらに発展させたい方へ: テスティングのスキルの重要性にお気づきでしょうか?テストを正しく書き始めることが、唯一のファーストステップです。無料でダウンロードいただける私の書籍『RSpec & Test Driven Developmentの無料ebook』をどうぞお役立てください。
概要
原著者の許諾を得て翻訳・公開いたします。
2018/04/23: 初版公開
2022/01/27: 更新