- Ruby / Rails関連
Rails: ViewComponent の call と erb_template と html.erb を適切に使い分ける(翻訳)
Rails: ViewComponentのcallとerb_templateとhtml.erbを適切に使い分ける(翻訳)
ViewComponentには、ERB(もしくはSlim)やHTMLをレンダリングするメソッドが複数あります。
ViewComponentが最初にリリースされた当時は、以下の2つのオプションしかありませんでした。
- html.erbファイルに分離する
callメソッド
しかしViewComponent v3.0からはerb_templateという戦略も使えるようになりました。
erb_templateの働きは、本質的にcallメソッドと同じなのですが、ERBやプレーンHTMLにも書けます。callもerb_templateも、目的は余分なファイルを排除することです。コンポーネントファイルを1個にとどめることで、コンポーネントをすっきりと整理できるようになります。
🔗 3つの異なる戦略
3つの戦略について以下でそれぞれ解説し、続いて適切な戦略を選ぶためのガイドラインを示します。
🔗 1: erb.htmlファイル
これはViewComponentのデフォルトの方式であり、コンポーネントクラスのRubyファイルと同じディレクトリに配置したerb.htmlファイルでテンプレートを定義します。erb.htmlファイル内には、ERBやHTMLを記述できます。
# app/components/example_component.html.erb
<h1>Hello, <%= @name %>!</h1>
🔗 2: callメソッド
callメソッドは、コンポーネントのRubyファイル内にレンダリング用のロジックを書くときに使えます。このオプションでは、RailsのAction Viewのcontent_tagやtagといったヘルパーはもちろん、任意のRubyコードも使えます。
# app/components/example_component.rb
class ExampleComponent < BaseComponent
def initialize(name:)
@name = name
end
def call
content_tag(:h1, "Hello, #{@name}")
end
end
🔗 3: erb_template
3番目のerb_template戦略は、上の2つの戦略の合せ技とみなすことも可能です。以下のようにerb_templateにヒアドキュメントを併用することで、html.erbファイルにHTMLやERBを書くときと同じように書けます。
# app/components/example_component.rb
class ExampleComponent < BaseComponent
def initialize(name:)
@name = name
end
erb_template <<~ERB
<h1>Hello, <%= @name %>!</h1>
ERB
end
この<<~ERBという妙ちきりんな記法は、Rubyで"squiggly"ヒアドキュメントと呼ばれている構文で、複数行にまたがる文字列のインデントを削除して渡せます。
# ...
slim_template <<~SLIM
<h1>Hello, <%= @name %>!</h1>
SLIM
# ...
🔗 3つの戦略の使い分け方
では、どんなときにどの戦略を使えばよいのでしょうか?
私がこの数年間、ViewComponentでUIコンポーネントを構築するうちに、3つの戦略を適切に使い分けるためのベストプラクティスをつちかってきました。
私は以下のガイドラインを使っています(ガイドラインの常として、必要とあればしれっと変更します)。
callを使う- 表示するコンテンツが1行に収まる場合(
content_tag(:h1, "Hello, #{@name}")など) erb_templateとヒアドキュメントを使う- 表示するコンテンツが2〜11行程度の場合
html.erbファイルを使う- 表示するコンテンツが12行を超える場合
この数字はどこから来たのかって?call以外はさしたる根拠はありません。コンポーネントのコードが10行を超えると散らかって見えるものなので、別ファイルに切り出す方が便利です(見えなければ存在しないのと同じ!)。
実際のところ、erb_templateが導入されて以来、もっぱらerb_template戦略を使っています。
基準は人それぞれ違うでしょう。たとえば2〜19行の場合はerb_templateとヒアドキュメントを使うことにしても、私は一向に構いません。いずれにしろ、ガイドラインではチーム内で合意の取れた数字を使いましょう。ガイドラインが整備されていれば、考えるときの根拠になります。
お気づきの点がおありの方や、もっとよい方法をご存知の方は、ぜひメールでお知らせください。
関連記事
Rails: ViewComponent と Tailwind CSS や Hotwire を効果的に組み合わせる(翻訳)
概要
元サイトの許諾を得て翻訳・公開いたします。
日本語タイトルは内容に即したものにしました。