Ruby
Rails

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

More than 3 years have passed since last update.

エラーページを作ります

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

何がほしい

  • メンテナンス中
    • 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