RailsのビューをRubyで書く、.rubyというものの存在を知ったので、少しまとめてみます。
ビューの二重拡張子
Rails で使うビューには、index.html.erbとかshow.json.jbuilderのように、二重の拡張子が付与されています。このうち、前半の.htmlや.jsonは、レスポンスの形式を表すものであり、後半の.erbや.jbuilderは、テンプレートを処理するハンドラーの指定です。
ここで言及する.rubyも、そんなハンドラーとして使えるものです。
使い方
他のビューと同じように、app/views/controller_name/action_name.response_extension.rubyのようなビューファイルを作成して、その中には好きにRubyコードを書けます。
そして、出力は、メソッドを書く時と同様な感じで、ビューファイルの最後の行で実行した内容となります。
メリット
Railsの出力を構築する方法としては、「他のハンドラー形式を使用する」「renderやsend_dataなど、コントローラー内から結果を直接送信する」という方法が考えられますが、この2つと比較したRubyビューのメリットを挙げていきます。
他のハンドラーと比較してのメリット
- どんな形式でも出力できる…ERBでPNG画像を構築するのは非現実的ですし、 JBuilderはJSON専用ですが、Ruby形式であれば何に使うことも可能です。
- 自由度が高い…ハンドラーによっては特殊なDSLが作り込んであったりしますが、Ruby形式の場合はコードを書けば何でも可能です。
コントローラーからの出力と比較してのメリット
- ビューとしての枠組みに載せられる…レスポンスの形式による分岐やビューヘルパーの活用など、Railsのビュー標準で用意されている機能をそのまま利用可能です。
- コードの分離…描画専用のコードをビューに追い出すことが可能です。
デメリット
もちろん世の中に銀の弾丸などないので、Rubyでビューを作ることによるデメリットもあります。
他のハンドラーと比較してのデメリット
- 専用のハンドラーで書くより煩雑になる場合がありうる…テンプレートエンジンを使わずに、長大な文字列を組み立てるのは苦行でしょうし、特定の形式で出力するために特定のライブラリを使うような場合でも、Rubyビューでは決まりきった動作まで書かないといけません。
(余談)ハンドラーの登録について
Railsにビューハンドラーを追加するには、ActionView::Template::Handlers.register_template_handlerというメソッドを使います。ハンドラーは、.call(template)というメソッドを持っていて、与えられたtemplateからRubyのソースコード文字列を生成する、という処理を行います(その後、ActionView::CompiledTemplatesに当該の文字列からメソッドを作って登録されることとなります)。
で、Railsのリポジトリを見てみたところ、ERBやRawといったハンドラーがActionView::Template::Handlers内に存在しているのですが、Ruby用のが見つからない状況です。さらに調べてみると、このハンドラーは驚くべきものでした。
base.register_template_handler :ruby, :source.to_proc
ハンドラーに渡されるtemplateには、ソースコードを取得するsourceメソッドがあるので、それを呼べば用は片付いてしまう、ということでした。