経緯
ActionViewのヘルパーメソッドについて勉強していたら、 ActionView::Helpers::TagHelperクラスのcontent_tagメソッドを用いて、ビューヘルパーを自作できることが分かりました。
そこで今後も繰り返し使えそうなkey−valueペアの表を生成するメソッドを作ることにしました。
実はもうちょっと複雑な表を作ろうと思ったのですが、入れ子構造が深くなるとうまくできませんでした。悩むくらいならpartialを作った方が早そうです。
#手順
####1. /app/helpers/配下のファイルでメソッドを自作。
以下の例ではkv_table_forメソッドを定義します。便宜上BootstrapのCSSクラスが加えてあります。
module ApplicationHelper
# kv_names: 配列 [key名, value名]
# collection: hash { key1: value1, key2: value2, ... }
def kv_table_for(kv_names, collection={})
thead = content_tag(:thead) do
content_tag(:tr) do
tags = kv_names.map { |column| content_tag(:th, column, class: "text-center") }
safe_join tags
end
end
tbody = content_tag(:tbody) do
tags = collection.map do |k, v|
content_tag(:tr, class: "text-center") do
concat content_tag(:td, k)
concat content_tag(:td, v)
end
end
safe_join tags
end
content_tag(:div, class: "table-responsive") do
content_tag(:table, class: "table table-bordered table-hover table-striped") do
thead + tbody
end
end
end
end
####2. データを渡し、テンプレートから呼ぶ。
テンプレートはHAMLで書いています。
これで今後は、一行のみで同様の表を作成することができます。
= kv_table_for %w(category volume), @items.group(:category).sum(:volume)
誰かが作った便利なGems
当然ながらこういうメソッドを自作しなくても、既に誰かが便利なGemを作っています。
- nizovtsevnv/table_for_helper
- [pluginaweek/table_helper]
(https://github.com/pluginaweek/table_helper)
しかしながら、これらは全然メンテナンスされてない様子なので、やっぱり、自分でわかる範囲で都度やった方が無難そうです。
#考察
Railsにはpartial等便利な選択肢が多数ありますので、あえてビューヘルパーを自作する機会は少ないように思われます。しかしながら、いつも同じ書式でデータを変更するのみの部品があれば、ビューヘルパーを自作することにより、link_to等の様に便利に使い回しができそうです。通常のHTMLと比較して直感的に読みにくいので、複雑な構造には向いていない様に思われます。
#参考資料
- http://stackoverflow.com/questions/4205613/rails-nested-content-tag
- http://stackoverflow.com/questions/3863844/rails-how-to-build-table-in-helper-using-content-tag
- http://railscasts.com/episodes/208-erb-blocks-in-rails-3
- http://apidock.com/rails/ActionView/Helpers/OutputSafetyHelper/safe_join
- http://apidock.com/rails/ActionView/Helpers/TextHelper/concat