この記事はソニックガーデン プログラマ アドベントカレンダーの3日目の記事です。
Rails の Helper に関する小ネタです。タイトルの通り、長ったらしいマークアップを Helper に押し込むことで、View をスッキリさせようという話です。
Stimulus を使っていると長ったらしいマークアップを要求されることがままあります。
例えばこんな Stimulus コントローラがあるとします:
application.register('class-toggle', class extends Controller {
static targets = ['element']
static values = { className: String }
toggle(ev) {
for (const el of this.elementTargets) {
el.classList.remove(this.classNameValue)
}
const { currentTarget } = ev
currentTarget.classList.add(this.classNameValue)
}
})
これを使うマークアップは、べたっと書くとこうなる想定です。
%div{ data: { controller: 'class-toggle', class_toggle_class_name_value: 'active' } }
%button{ data: { class_toggle_target: 'element', action: 'class-toggle#toggle' } } 赤
%button{ data: { class_toggle_target: 'element', action: 'class-toggle#toggle' } } 橙
%button{ data: { class_toggle_target: 'element', action: 'class-toggle#toggle' } } 黃
%button{ data: { class_toggle_target: 'element', action: 'class-toggle#toggle' } } 緑
%button{ data: { class_toggle_target: 'element', action: 'class-toggle#toggle' } } 青
%button{ data: { class_toggle_target: 'element', action: 'class-toggle#toggle' } } 藍
%button{ data: { class_toggle_target: 'element', action: 'class-toggle#toggle' } } 紫
長ったらしいですよね。プロダクションコードではもっとたくさんの属性を指定するケースも珍しくありません。
そこで Helper です。
module ButtonToggleHelper
def toggleable_button_tag(label)
tag.button(label, data: { class_toggle_target: 'element', action: 'class-toggle#toggle' })
end
end
このヘルパーメソッドを使うと、マークアップは以下のようにスッキリします。
%div{ data: { controller: 'class-toggle', class_toggle_class_name_value: 'active' } }
= toggleable_button_tag '赤'
= toggleable_button_tag '橙'
= toggleable_button_tag '黃'
= toggleable_button_tag '緑'
= toggleable_button_tag '青'
= toggleable_button_tag '藍'
= toggleable_button_tag '紫'
単にスッキリしただけでなく、マークアップが DRY になったので、Stimulus コントローラ側に修正が入っても、マークアップの修正を最小限に抑えることができます。
今回は長ったらしいマークアップを求められる状況の例として Stimulus を引き合いに出しましたが、他にも例えば TailwindCSS なんかも同じような状況になりがちかなと思います。Stimulus 以外にも応用できるノウハウだと思っています。
というわけで、Helper を有効活用することで、View をスッキリさせていこうというお話でした。
4日目は @kontikun です。お楽しみに!