96
89

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Rails 4.x] エラーページの作り方

Posted at

エラーページを作ります

オシャレなエラーページがあるととても素敵だなぁと思います。

何がほしい

  • メンテナンス中
    • Maintainance
  • 貴方はこのページを見る権限ないよー
    • Forbidden
  • IP制限引っかかってるよー
    • IpAddressRejected
  • そんなURL無いよー
    • RoutingError
  • URLの:idのトコとか勝手にいじっても、レコードないもんはないよー
    • ActiveRecord::RecordNotFound

仕組み

各処理の中で、エラーをraiseさせて、それをapplication_controllerで拾ってエラーページを出力させてあげる感じ。

とりあえずview

app/views/errors ディレクトリを作成し、その中に

  • forbidden.html.erb
  • not_found.html.erb
  • internal_server_error.html.erb

を作成。
中身は後からでもいつでもいい。

app/controller/concerns/error_handlers.rb

ここに処理を書きます。
raiseされたエラーをrescue_fromで拾っています。

module ErrorHandlers
  extend ActiveSupport::Concern

  included do
    rescue_from Exception, with: :rescue500
    rescue_from ApplicationController::Forbidden, with: :rescue403
    rescue_from ApplicationController::IpAddressRejected, with: :rescue403
    rescue_from ActionController::RoutingError, with: :rescue404
    rescue_from ActiveRecord::RecordNotFound, with: :rescue404
  end

  private
  def rescue403(e)
    @exception = e
    render 'errors/forbidden', status: 403
  end

  def rescue404(e)
    @exception = e
    render 'errors/not_found', status: 404
  end

  def rescue500(e)
    @exception = e
    render '/errors/internal_server_error', status: 500
  end
end

app/controllers/application_controller.rb

以下を追記。

class Forbidden < ActionController::ActionControllerError; end
class IpAddressRejected < ActionController::ActionControllerError; end

include ErrorHandlers if Rails.env.production? or Rails.env.staging?

ErrorHandlersをincludeするのは、一応dev環境では避けます。開発の妨げになりそうなので。

RoutingError

config/routes.rb

一番下に追記。

get '*anything' => 'errors#routing_error'

routes.rb内は、上から順に優先度高いので、一番下にこの様に書くことで、指定されていない残りのurlを全て処理できます。
つまり、適当なurl入力への対応が出来ます。

app/controllers/errors_controller.rb

routingエラー用のコントローラーを設置します。

class ErrorsController < ApplicationController
  def routing_error
    raise ActionController::RoutingError, "No route matches #{request.path.inspect}"
  end
end

最後にview

viewを書き込みます。

テスト

事前準備

環境を選択して、整えます。

  • application_controllerのerror_handlersのincludeの環境制限をコメントアウトして、devでも読み込むようにして、devでテスト
  • rails s -e productionとして本番環境でテスト
    • 本番とdevでdb環境が違うと、database.ymlで引っかかることもあるかも

キャッシュ設定

選択した環境のconfigでcache_classesをfalseにします。
config/environments/*.rb

やりかた

  • 指定外のURLに飛ぶ
  • 各処理中の良きところで、raiseさせます。
    • raise
    • raise IpAddressRejected
    • raise Forbidden
    • など

参考

実践 Ruby on Rails 4

96
89
1

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
96
89

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?