Railsの技: カスタムヘルパーとStimulusで軽量コンポーネントを構築(翻訳)
Railsのカスタムヘルパーのよさは見落とされがちですが、軽量コンポーネントのビルドや、Stimulusコントローラの定形コードを削減するときの最適なオプションにもなります。
Stiumulusの良い点は、マークアップの属性を見るだけで即座に機能を推測できることです。しかし、値やアクションを複数持つコンポーネントの場合は実装の詳細の一部を隠蔽することにメリットがあります。
私の過去記事『Building GitHub-style Hovercards with StimulusJS and HTML-over-the-wire』からコード例を引用します。
<div class="inline-block"
data-controller="hovercard"
data-hovercard-url-value="<%= hovercard_shoe_path(shoe) %>"
data-action="mouseenter->hovercard#show mouseleave->hovercard#hide"
>
<%= link_to shoe.name, shoe, class: "branded-link" %>
</div>
このhovercard_controller
はurl
値を渡される必要があり、かつマウスオーバーされたカードの表示と非表示用のアクションを追加する必要もあります。このコントローラはリンクタグでラップされており、アプリで用いるホバーカードの種類に応じてカスタムスタイルを適用できるようになっています。
このコントローラを数箇所で使うだけなら大した手間ではありませんが、さまざまな種類のホバーカードに対してこのコントローラを再利用したいのであれば、Railsのカスタムヘルパーを追加してみてはいかがでしょう。
利用法
app/helpersディレクトリの下に置かれたモジュールは、自動的にアプリのビューで利用できるようになります。
# app/helpers/hovercard_helper.rb
module HovercardHelper
# ヘルパーを用いてStimulusコントローラ属性の繰り返しを避ける
def hovercard(url, &block)
content_tag(:div,
"data-controller": "hovercard",
"data-hovercard-url-value": url,
"data-action": "mouseenter->hovercard#show mouseleave->hovercard#hide",
&block)
end
# 独自の軽量「コンポーネント」をビルドする
def repo_hovercard(repo, &block)
hovercard hovercard_repository_path(repo), &block
end
def user_hovercard(user, &block)
hovercard hovercard_user_path(user), &block
end
end
ヘルパーを使えば、独自の「コンポーネント」をRubyで作成して実装の詳細を抽象化できるようになります。Rubyのブロックは強力なので、用途に応じてカスタマイズ可能な柔軟なコンポーネントを作れます。
<!-- app/views/timeline.html.erb -->
<%= user_hovercard(@user) do %>
<%= link_to @user.username, @user %>
<% end %>
<%= repo_hovercard(repository) do %>
<div class="flex items-center space-x-2">
<svg></svg> <!-- Some icon -->
<%= link_to repository.name, repository %>
</div>
<% end %>
たとえばrepo_hovercard
というヘルパーを作って、Repository
モデルとレンダリングするブロックを受け取れるようにしたとします。これにより、ページのコンテキストに応じて表示内容を完全に制御でき、Stimulusイベントの適切な組み合わせを気にする必要もありません。
アプリのStimulusコントローラを変更したい場合も、コントローラが多くのビューに分散せず1箇所に集約されます。
参考情報
- Rails APIドキュメント: Helpers
概要
原著者の許諾を得て翻訳・公開いたします。
日本語タイトルは内容に即したものにしました。