Refinementsを使ったRails Presenter
Ruby2.1のRefinementsを使って、RailsのPresenter層ライブラリを作れるんじゃないかと週末にがんばってみたところ、いい感じに実装できた。
現状はサンプルのRailsアプリケーションで動くようになったところ。
https://github.com/kmdsbng/refinements_rails_presenter_test
動きを一言で説明すると、特定のViewのファイルでのみ、refineで定義したメソッドが生える。例えば、あるViewでのみ、modelにメソッドを生やす、ということができる。
これはRuby2.1のRefinementsの機能を使って実現してるだけなんだけど、Viewのなかでusingを呼び出すだけでは動いてくれなかったので、動くようにActionpackに手を加えてる。
まず、refine定義するモジュールのサンプル。
普通にrefineを使って、Postモデルにメソッドを定義してる。これはAutoLoadされるディレクトリならどこに置いてもいい。
refinemehts rails presenter sample
これがViewの定義。 slimで書いてる。
先頭の using と書いてる行で、refineを定義しているmoduleを指定してる。
これで、このViewではPost#body_lengthが使えるようになる。
usingがViewの中で使えるなら、特別な処理の必要はなかったんだけど、残念ながら using は現状トップレベルからしか呼び出せないという制限がある。
だから、Viewテンプレートをevalしてるところで、usingを加えてevalするようにモンキーパッチを当てたところ、うまくいった。
Draperなどの既存のRails Presenterライブラリは、 modelをラップしたりextendを使ったりして model の機能拡張を行ってる。このやり方だとmodelインスタンスすべてに処理しないといけないのでどうしても手間がかかってしまったが、Refinementsが使えるならもっとスマートに同様の機能が実現できる。かなり有望なアプローチだと思う。