Hanami::Controllerで共通の処理を差し込む
Meetup #100 - Kanazawarb に参加したらちょっと高まったので!
Hanamiは比較的継承が少ない
Hanami のコードの一つの特徴として、「継承を避けて mixin を使いがち」というものがある。もう少し具体的には
パス | 実現方法 |
apps/ | Action も View も moulde の mixin |
lib/ | Hanami::Entity も Hanami::Repository も継承 |
lib/*/mailers/ | mixin |
db/migrations/ | 単なる DSL |
のようになっていて、簡単に言うと Rails のようには
ApplicationController にメソッドを追加したらすべての controller で使える、みたいな素朴な OOP が通用しない
ようになっている。
これはこれで巨大な superclass を作らないようにさせる矯正ギプスとして面白いなと思う反面、mixin が多くなるのは Ruby 力を要求しやすいのでは? という気もしないでもない。
ApplicationControllerの代わりになるもの
application.rb の中の
module Web
class Application < Hanami::Application
configure do
..
# Handle exceptions with HTTP statuses (true) or don't catch them (false).
# Defaults to true.
# See: http://www.rubydoc.info/gems/hanami-controller/#Exceptions_management
#
# handle_exceptions true
controller.prepare do
# include MyAuthentication # included in all the actions
# before :authenticate! # run an authentication before callback
end
end
end
end
ここ。
Controllerのbefore, after callback
Actions: Control Flow | Hanami Guides
Controller には before / after の callback があって、Symbol を使ってメソッドを呼んだり、直接 block を与えたりすることができる。これは Rails の Controller によく似ていて、この before / after メソッドを 上の controller.prepare block にも与えることができる。
もし ApplicationController の before / after で処理を加えていたのなら、ここに同じように書くことができる。
configure do
controller.prepare do
before do
..
end
end
end
また、この中で self を参照すると実際に request を受けた Controller を取得できる。
例外を拾う
例外を拾う方法は以下のようになっている。
フレームワーク | 例外を処理するメソッド |
Rails | rescue_from |
Hanami | handle_exception |
Rails の ApplicationController で言う rescue_from は Hanami では handle_exception になるんだけど、これも上の before / after と同じように Action に該当する class 内に書いても controller.prepare に与える block 内に書いても同じように動作する。
ただし、development では handle_excepions が false になっているので、
configure :development do
- handle_exceptions false
+ handle_exceptions true
end
に変更しておかないと実際のエラーを目視しながら開発することはできない。これも Rails と同じだと思う。