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::Layoutssimply overrides_normalize_optionsto support the:layoutoption.
もし置き換わっているなら 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定数