Crafting Rails4 Applications 覚え書き
この記事に書いてあること
Crafting Rails 4 Applications Expert Practices for Everyday Rails Developmentを読み次のことを記載している。
- Outline・・・各章で学んだことをざっくりとまとめている。
- Diff・・・本書で扱われているバージョンと異なるもの(Rails6)で進めているため、参照先のソースコードが本に記載されている内容と異なることがある。そこについて記載している。
- DevTips・・・実際に手を動かしている中で気になったことを記載している。
- Question・・・本書を読んでいて心配なことや気になったことを記載している。
1. Creating Our Owner Render
Rails のレンダリング処理を読み解いていく章。
1.1 Creating Your First Rails Plug-in ~ 1.2 Writing the Renderer
Outline
pdf_renderer
という Gemを実装することで、render
メソッドが :pdf
のようなオプションを渡された時に、どのような処理が行われているのかをRailsのソースコード(正確には、actionpack
)を見ながら理解した。
具体的には、rails/actionpack/lib/action_dispatch/http/mine_type.rb
にContentTypeに対応するMINETypeをセットにしたコードがあり、それを元に :pdf
の対になるMINEType(application/pdf)を決めていた。
Diff
TODO
DevTips
- [未解決] ダミーアプリを起動する
test/dummy
配下で rails server
を実行することでサーバーが起動され、http://localhost:3000/home.pdf
にアクセスができると記載があるが、サーバーが無いと怒られる。
% rails s
Could not find server "".
Run `bin/rails server --help` for more options.
% rails s -u puma
Could not load server "puma". Maybe you need to the add it to the Gemfile?
gem "puma"
Run `bin/rails server --help` for more options.
Question
なし。
1.3 Understanding the Rails Rendering Stack
Outline
AbstractController::Rendering#render
を呼び出した時のレンダリング処理がどのように走っていくのかを読み解いていく。
Rails2.3では、Viewが自動的にControllerに定義されているインスタンス変数を取得していたが、Rails3.0からは、ControllerでViewに渡すインスタンス変数をハンドリングできるようになった。
例えば、Rails2.3だとViewにインスタンス変数を取得させたくない場合、それを定義しないかレンダリングの前にそれを削除する必要があったが、Rails3.0からは view_assigns()
をオーバーライドすることで、これをハンドリングできるようになった。
class UsersController < ApplicationController
protected
def view_assings
{}
end
end
レンダリング処理にフックし機能を拡張してくれるモジュールたち。
AbstractController::Layouts
・・・ActionController::Rendering#_normalize_options
をオーバーライドすることで、:layout
オプションをサポートする(*Diffの1を参照)ActionController::Rendering
・・・AbstractController::Rendering#render
をオーバーライドすることで、DoubleRenderError
が発生するようにしている。また、AbstractController::Rendering#_process_options
をオーバーライドすることで:location
,:status
,content_type
オプションをハンドリングできるようになるActionController::Renderers
・・・:pdf
のようなキーに対応できるようにするActionController::Instrumentation
・・・AbstractController::Rendering#render
をオーバーライドすることで、レンダリング処理にかかった時間を計測できるようになるActionController::Streaming
・・・AbstractController::Rendering#_process_options
をオーバーライドすることで、適切なHTTPヘッダを設定して:stream
オプションを処理できるようになり、また、ActionController::Streaming#_render_template
によってテンプレートがストリームを処理できるようになる。
Diff
AbstractController::Layouts
が存在しない。
Rails6では、AbstractController::Layouts#_normalize_options
は ActionController::Rendering#_normalize_options
に置き換わっている?
AbstractController::Layouts
simply overrides_normalize_options
to support the:layout
option.
もし置き換わっているなら ActionController::Rendering#_normalize_options
には、:layout
オプションに関する処理が書いてありそうだが、そのような処理はないので別物っぽい。
DevTips
- Gemのソースコードにデバッガーを仕込んでデバッグする
本書の内容ではないが、デバッグしならがらの方が理解度上がると思ったので、pry-byebugをインストールした。
その他、デバッグしたいGemのソースコードは bundle open
コマンドで開いて、bundle pristine
で変更を戻していた。
Question
AbstractController::Rendering#_process_options
は空実装で、ActionController::Rendering#_process_options
をどのようにして呼び出しているのか。ActionController::Streaming#_render_template
はどこから呼ばれているか。
1.4 Taking It to the Next Level
Outline
この章で実装したGem(pdf_renderer
)は、render_to_string()
を呼び出しいるので、template:
を渡すことで明示的にテンプレートを指定することができることがわかった。
そこで、実際にテスト用アプリケーションのコントローラーにテンプレートを指定したアクション(another
)と、それ用のテストケースを追加して、:pdf
が template:
を引数に取れることを証明した。
Diff
なし。
DevTips
なし。
Question
なし。
1.5 Wrapping Up
Outline
- この章でPDF用のレンダラーGemを実装した
- この実装方法に沿えば、CSVやATOMなどもレンダリングできるようになるし、HTMLをPDFに変換するようなライブラリをラッパーしたものも実装できる。
- Railsのレンダリング処理とモジュール性の説明
Diff
なし。
DevTips
なし。
Question
なし。
参考記事
2. Building Models with Active Model
この章では、次のことを見ていく。
- ActiveModelとそのモジュール
- オブジェクトをRailsが要求するActive Model APIに適合させる方法
- バリデータとRuby定数