Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Crafting Rails4 Applications読み回 1. Creating Our Own Renderer

3,385 views

Published on

一部有志で行ったCrafting Rails4 Applicationsの読み回資料です

Published in: Technology
  • Be the first to comment

Crafting Rails4 Applications読み回 1. Creating Our Own Renderer

  1. 1. Crafting Rails4 Applications 1. Creating Our Own Renderer
  2. 2. Renderer • render()メソッドによりクライアントに返す形式 を柔軟に変更することができる Post.allの結果をJSONに変換して返す app/views/shared/not_authenticatedで始まる所定の ファイル内容を返し,HTTPレスポンスコード401を返す
  3. 3. Creating Rails Plugins
  4. 4. rails plugin new pdf_renderer • Rails pluginのgenerator Treeで出したディレクトリツリー ライブラリ本体 テスト用ディレクトリ
  5. 5. testディレクトリ以下の構造 dummy以下にあるのはどうみてもRailsアプリそのものです.本当にありがとうございました
  6. 6. ${PLUGIN_NAME}.gemspec • Gemのサマリ情報を書く
  7. 7. Rake tasks • Plugin用のRakeタスクがちょいちょい – Rake releaseでRubygemsにpushできるらしい – testの実行はrake test
  8. 8. Dummy application • 基本的に普通のRailsプロジェクトと同じ – アプリケーション名はdummy • rails new dummy でできるファイル群とほぼ同じ – 一応diffしてみたけれども,確かにほとんど同じ
  9. 9. PDF Rendererを作る
  10. 10. actionpack/lib/action_controller/metal/renderers.rb • とりあえず眺めてみると, – ActionController::Renderers::_renderersにSetが入ってい る – _renderersはActionController::Renderers::add()で追加で きる • add(key, &block)の中では_render_option_#{key}を define_methodしているだけ – デフォルトで:json, :js, :xmlが定義されている • 何気にJSONPのオプション(callback: true)も用意されていた
  11. 11. PDF Renderer作ろうぜ • こういうのを作りたい • rendererを拡張すれば,Railsの流儀に従ってい い感じにPDF出力できるじゃん!!
  12. 12. Pluginにgemのdependency追加 • Pluginでgemを使う場合,Gemfileではなくgemspecに書く – 書いた後は普通にbundleすればdependしたgemが入る pdf_renderer.gemspec • この辺の定義はGemfileにあった Gemfile この記述でgemspecのdependencyを読み込んでいるみたい
  13. 13. とりまPrawn irb/pryでかきましょー
  14. 14. 振る舞いとテストまで書いてみる
  15. 15. 動作確認・開発の方法 • test/dummyにcdすれば,普通にrails sできる – 普通のRailsアプリと同様に開発できるよー lib/pdf_renderer.rb この記述で:pdfをrender()が解釈できるようになる
  16. 16. MIME typeの設定 • テストを見ると,content-type: application/pdfが勝手に付与されて いるが,これはたまたまPDFの設定がデフォルトであったから Actionpack/lib/action_dispatch/http/mime_types.rb • もしここに設定されていないcontent-typeを指定したい 場合,config/initializers/mime_types.rbに書けば良い Rails newデフォルトのconfig/initializers/mime_types.rb スマホ向けの出し分けなんかで触ったことある人もいるのでは?
  17. 17. Rendererを潜る
  18. 18. Render()の流れ 引数を展開して正規化されたoptions hashを作る Renderのoptionが色々な形式に対応しているのはこの辺がやってる render(:new)とか,render(partial: true)みたいなものを受けて,正しい Action_nameに変換したりする HTTP bodyに関係の無い部分をoptionsに沿って処理する. status: 401とかそういうの view_renderer.render(view_context, options)を呼び出す view_contextはActionView::Baseのインスタンス
  19. 19. _render_template周り • lookup_contextがformat情報を保持しているっぽい – どのテンプレートが呼び出されるのかの選択に使われる view_renderer view_context
  20. 20. Controller -> Viewへの値渡しについて • Rails 2.3系まで – ViewがControllerのインスタンス変数を取りに行って いた • Rails 3.0から – ControllerからViewに渡すインスタンス変数を明示的 に指定できるようになった こうするとViewにインスタンス変数が渡らなくなる
  21. 21. 拡張するぜ
  22. 22. AbstractController::Layouts • Renderingの_normalize_optionsをoverrideし た ・・・
  23. 23. もっと拡張
  24. 24. ActionController::Rendering • DoubleRenderErrorのチェックとか, status/content_type/location optionの処理
  25. 25. ActionController::Renderers • 特定のsymbol渡しで特殊処理させるための ひな形達
  26. 26. ActionController::Instrumentation • 処理時間の計測
  27. 27. ActionController::Streaming • HTTP/1.1 Chunkedを使ったRailsのStreaming API
  28. 28. render と render_to_string • 違いは見ればわかるよね? – pdf_rendererみたいにrenderした中身をstring取得したい時には便利 – render_to_stringは,DoubleRenderErrorは発生しない (ActionController::Rendering#renderに実装されているため) – 同じ理由でrender_to_stringはctionController::Instrumentationによっ てベンチマークされない
  29. 29. 話を戻すと • render_to_string({}) – _normalize_options()でoptions = template: ”#{controller_name}/#{action_name}” を生成している
  30. 30. 何もしなくても:template optionは使える pdf_renderer.rb
  31. 31. おまけ:ActionController::Base ApplicationController < ActionController::Baseで読み込まれるmodule群
  32. 32. まとめ • PDFフォーマットのファイルを返す pdf_rendererを作る中で,Railsのrendering stackを追ってみたよ • Rendering stackはモジュール化されているの で,renderや_normalize_optionsなどのエント リポイントで任意の処理を追加することができ るぞ

×