Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

Rails: ViewComponent の call と erb_template と html.erb を適切に使い分ける(翻訳)

概要

元サイトの許諾を得て翻訳・公開いたします。

日本語タイトルは内容に即したものにしました。

Rails: ViewComponentのcallとerb_templateとhtml.erbを適切に使い分ける(翻訳)

viewcomponent/view_component - GitHub

ViewComponentには、ERB(もしくはSlim)やHTMLをレンダリングするメソッドが複数あります。
ViewComponentが最初にリリースされた当時は、以下の2つのオプションしかありませんでした。

  • html.erbファイルに分離する
  • callメソッド

しかしViewComponent v3.0からはerb_templateという戦略も使えるようになりました。
erb_templateの働きは、本質的にcallメソッドと同じなのですが、ERBやプレーンHTMLにも書けます。callerb_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_tagtagといったヘルパーはもちろん、任意の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の「スロット」を極めるための活用ガイド(翻訳)

Rails: ViewComponent と Tailwind CSS や Hotwire を効果的に組み合わせる(翻訳)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。