はじめに
プログラミングにおいてエラーは無いにこしたことはありませんが、開発者も人間なのでミスすることもあるし、ネットワークのエラーで開発者がどうしようもなくエラーが発生することもあります。
エラーと言っても色々な種類があります。「こういうエラーが起きた場合はこうする」という処理を書いておくべき場面は多々ありますが、そんな時に使えるrescueとrescue_fromについての基礎的な使い方です。
rescue
rescueを使うと、エラーが発生した場合それを拾って次に行う処理を書くことができます。
以下はrescueがない場合とある場合の違いです。
Userクラスはnameカラムしか持たないようにして、あるuserを作ります。
> user = User.new('山田')
=> #<User:0x00007ff0fa896758 @name="山田">
> user.name
=> "山田"
Userクラスにputs_infoメソッドを作り、実行します。
class UsersController < ActionController::Base
def puts_info
"名前は" + name
end
end
> user.puts_info
=> 名前は山田
puts_infoメソッドに存在しないageメソッドを加え、実行します。
class UsersController < ActionController::Base
def puts_info
"名前は" + name
"年齢は" + age
end
end
> user.name
=> "山田"
> user.puts_info
=> NameError (undefined local variable or method `age' for #<User:0x00007fdeb98f3ed8 @name="山田">)
NameErrorになりました。
rescueを使って、エラーの場合の処理を書いてあげます。
class UsersController < ActionController::Base
def puts_info
"名前は" + name
"年齢は" + age
rescue => e
"エラーです"
end
end
> user.puts_info
=> "エラーです"
rescue NameError => e
のように例外クラスを指定して拾うこともできます。
詳しく知りたい方は以下の記事がおすすめです。
rescue_from
rescue_from
は、特定の種類または複数の種類の例外を1つのコントローラ全体およびそのサブクラスで扱えるようになります。
例:404エラー(そんなページありませんよ)の場合にrecord_not_found
というメソッドを実行させる。
class UsersController < ActionController::Base
rescue_from ActiveRecord::RecordNotFound, with: :record_not_found
private
def record_not_found
render plain: "404 Not Found", status: 404
end
end
例:adminユーザー以外はeditページに入れない、という仕様を実装する
1, Clientコントローラーで、editアクション実行前にbefore_action
で権限チェックの処理を行います。
check_authorization
メソッド内でcurrent_user.admin?
を行い、管理者ではない場合は、raise
を使ってUser::NotAuthorized
という例外を発生させます。
class ClientsController < ApplicationController
before_action :check_authorization
def edit
@client = Client.find(params[:id])
end
private
def check_authorization
raise User::NotAuthorized unless current_user.admin?
end
end
2, ApplicationControllerに、User::NotAuthorized
というエラーの場合にuser_not_authorized
メソッドを実行させる処理を書きます。
class ApplicationController < ActionController::Base
rescue_from User::NotAuthorized, with: :user_not_authorized
private
def user_not_authorized
flash[:error] = "あなたはこのページにアクセスする権限がありません。"
redirect_back(fallback_location: root_path)
end
end
こうすることで、権限エラーの場合には「権限がありません」という表示をしてあげることができますし
、editアクション内では権限に関して心配する必要がなくなります。
edit以外にも管理者権限を必要とするメソッドがある場合には、before_actionを使ってcheck_authorization
を実行してあげればいいですね。
参考