29
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

rescueとrescue_from

Last updated at Posted at 2020-08-23

はじめに

プログラミングにおいてエラーは無いにこしたことはありませんが、開発者も人間なのでミスすることもあるし、ネットワークのエラーで開発者がどうしようもなくエラーが発生することもあります。
エラーと言っても色々な種類があります。「こういうエラーが起きた場合はこうする」という処理を書いておくべき場面は多々ありますが、そんな時に使える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を実行してあげればいいですね。

参考

29
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?