Share
Embed
render 出来るオブジェクトの作り方
Gotanda.rb#56 (https://gotanda-rb.connpass.com/event/304333/) で発表した資料です
Tomoya Chiba
December 20, 2023
Transcript
14 slides
-
千葉 知也 (@tomoasleep) Qiita 株式会社 エンジニア 五反田 のオフィスから来ました SNS (?)
https://twitter.com/nemunemu3desu https://qiita.com/tomoasleep 自己紹介 2 -
class HelloComponent def render_in(view_context) view_context.content_for(:title, "Hello") view_context.content_tag(:p, "Hello, World!") end
end <%= render HelloComponent.new %> Rails 6.1 で追加された機能 Introduce support for 3rd-party component frameworks by joelhawksley · Pull Request #36388 · rails/rails で追加 render_in メソッドを実装しているオブジェクトを渡せる render_in メソッドの引数には ActionView::Base のインスタンスが渡さ れる 返り値が表示する内容になる render にオブジェクトを渡せるようになった 5 -
Controller から render するには format メソッド も必要 layout は通常通り適用される class
HelloPage def render_in(view_context) view_context.content_for(:title, "Hello") view_context.content_tag(:p, "Hello, World!") end def format :html # どの format かを指定 end end class HelloController def index render HelloPage.new # render renderable: HelloPage.new でも可 end end Controller からも呼べる 6 -
class HelloJSON def render_in(view_context) '{ "type": "json" }' end def
format :json end end class HelloController def index render HelloJSON.new end end $ curl -i localhost:3000 HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { "type": "json" } 例 : Content-Type もいじれる 7 -
https://viewcomponent.org/ 再利用性の高い View のパーツを実装するためのフレームワーク render に monkey patch をして ViewComponent
を渡せるようにしていたが、そ れが Rails 本体に取り込まれた class MessageComponent < ViewComponent::Base erb_template <<-ERB <h1>Hello, <%= @name %>!</h1> ERB def initialize(name:) @name = name end end <%= render(MessageComponent.new(name: "World")) %> 機能の背景 : ViewComponent 8 -
partial などに不満があり、Ruby でガッツリ View を実装したい場合 → ViewComponent をまず検討したほうが良いと思う ViewComponent の機能をそこまで使うことがないケース
→ 内製してしまうのもありかも ( この後紹介) render 出来るオブジェクトを何で作るか 9 -
Qiita では Rails の View → React での View への移行を進めている
すると Rails 側の View 実装がスカスカに 変数をバケツリレーするだけの冗長なコードに <% content_for :title, "Page Title" # タイトルを指定 content_for :description, "Description" # meta tag とかの項目を指定 component = react_component( # React on Rails の機能で React Component を埋め込む 'HelloReactPageComponent', props: { item: @item, user: @user, }, ) %> <%= component %> Qiita での実用例 10 -
タイトルを設定、 React Component を埋め込むだけのパターン化した View を Render するためのクラスを定義 class ReactView
def initialize(component, title:) @component = component @title = title end def render_in(view_context) view_context.content_for(:title, @title) view_context.react_component( @component.name, props: @component.props, ) end end 定型化した View を render 出来るオブジェクトとし て実装 11 -
Controller から直接 React の View を埋め込めるように class HelloController def index
render ReactView.new( HelloReactPageComponent.new( props: { item: @item, user: @user, }, ), title: "Page Title", description: "Description", ) end end Qiita での使い方 12 -
Introduce support for 3rd-party component frameworks by joelhawksley · Pull
Request #36388 · rails/rails https://github.com/rails/rails/pull/36388 Rails 6.1 の Renderable objects でお手軽に脱 ERB する #Ruby - Qiita https://qiita.com/tomoasleep/items/5c1cf71c1148c2737ca2 実装を見たい rails/rails で Renderable, render_in を検索 References 14