3
2

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.

Rambulanceを拡張して無理やりURL毎にエラーページを切り替える

Last updated at Posted at 2018-12-21

この記事は

  • Rambulanceでやりたいことやろうとしたら若干拡張機構使う必要が出たのでメモです

やりたかったこと

  • Railsの例外機構をシンプルかつ堅牢にすることができるRambulanceというgemがあります
  • 便利なのですが、同一のRailsアプリの中では単一のデザイン(=layoutsファイル)しか定義することができません
  • 今回URLによってデザインが諸々異なり、別のlayoutsを指定したかったです

ダメだった方法

Rambulanceが複数layoutに対応してないか?

  • そもそもRambulanceは複数のlayout指定に対応していません
  • ソースも見ましたが、思いっきり単一の@layout_nameに持っちゃってます

Rambulanceを無視してrescue_fromを書く

  • 特定のコントローラにrescue_fromを書いてしまって、処理の中で強制的にデザインの異なるエラー画面にredirectしてはどうかと考えました
  • が、Ramulance様はRack middlewareの根っこを抑えている神なので、rescue_fromなんていう瑣末な雑魚メソッドは完全に無視されてしまいダメでした

正解

RambulanceのCustom Exceptions Appを作成する

  • READMEをよく読んでみるとCustom Exceptions Appというものの記載がありました
  • ほとんど説明がないのでなんなのかは不明ながら、とりあえずそこに書いてある$ rails g rambulance:exceptions_appを実行してみました
  • すると、app/handlers/exceptions_app.rbにRambulanceの動きをカスタマイズできるExceptionsAppのソースが生成されました!

対応コード

  • どうもこのクラスはRambulanceの本体であるRambulance::ExceptionsAppを拡張するもののようで、Rambulanceのエラーページ表示の前に必ず通る場所のようです
  • 最大のポイントはActionController::Baseを継承しているので、Railsの大半のメソッドが使い放題!ということです
  • で、下記のようなコードを書いて、URLの頭が/otherで始まっている場合のみ、Rambulanceのエラー表示を横取りして、強制的に別レイアウトのページにredirectするようにしました
app/handlers/exceptions_app.rb
class ExceptionsApp < Rambulance::ExceptionsApp
  before_action :other_layout_filter

  private
  def other_layout_filter
    redirect_to '/other/error' if is_other_page?
  end

  def is_other_page?
    (params[:controller]&.split('/')&.first == 'other') rescue false
  end
end
  • 注意点としては、このファイルの修正をしたらdevelopmentモードだとしてもRailsを再起動しなくてはなりません

終わりに

  • 便利なライブラリは融通ききづらい時もあるけど、なんでもできる拡張の仕組みがあると、なんとか力技で対応できて助かりますね
3
2
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
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?