はじめに
Rails Tips の 31 回目です。なんだかんだで1月続いてしまいました。昨日から私がよく利用しているヘルパーメソッドをいくつか紹介しています。今日のは昨日の t_ars の応用版です。
labels
昨日の t_ars はモデルの属性名を取得するためのメソッドでした。モデルの index だと属性の一覧を作成することが多いです。そんな時こんな表を作ったりするのではないでしょうか。
西暦 | デフォルト年度 | 制御 |
---|---|---|
2024 | false | デフォルトに変更 |
2023 | true | |
2022 | false | デフォルトに変更 |
2021 | false | デフォルトに変更 |
以下 | 続く | デフォルトに変更 |
こんなとき、haml だと以下のような記述をするのではないかと思います。
%table.bordered %thead %tr - %w[西暦 デフォルト年度 制御].each do |w| %th= w %tbody (後略)
この部分、昨日の t_ars が使えそうですね。さらに楽をするために labels というヘルパーを作っています。こんな感じで使います。
%table.bordered %thead = labels Year, %i[year default_year], add_control: true %tbody (後略)
こちらのテストはこんな感じで書いています。キーワード引数ありの単一メソッド呼び出しはまだ紹介していませんでしたね。一緒に紹介します。
describe ApplicationHelper, type: :helper do subject { helper } describe "common test" do it_behaves_like "単一メソッド呼び出し(キーワード引数あり)" do let(:test_set) do { labels: [ [Year, %i[year default_year]], {}, "<tr><th>西暦</th><th>デフォルト年度</th></tr>", [Year, %i[year default_year]], {add_control: true}, "<tr><th>西暦</th><th>デフォルト年度</th><th>制御</th></tr>", ], } end end end end
単一メソッド呼び出し(キーワード引数あり)
以前紹介した単一メソッド呼び出し(
単一メソッド呼び出し shared_example: 小林研 Rails Tips (12) - hkob’s blog)は通常引数のみでキーワード引数には対応していないものでした。test_set を「通常引数」、「キーワード引数」、「検査する結果」の3つの繰り返しに変更したものです。キーワード引数を **k
で渡す処理を追加しただけになります。
shared_examples_for "単一メソッド呼び出し(キーワード引数あり)" do it "上述のメソッドの結果が正しいこと" do test_set.each do |method, answers| print "\tmst: #{method}\n" if documentation_formatter? answers.each_slice(3) do |(v, k, a)| expect(subject.send(method, *v, **k)).to eq a end end end end
labels の実装
labels は内部で t_ars を呼び出し、content_tag を concat で連結しているだけです。校務支援システムでは制御を最後の列に記述することが多いので、add_control が設定されている時だけ制御列を追加します。
# @param [Class] model モデルクラス # @param [Array<Symbol>] array アトリビュートkeyの配列 # @param [Boolean] add_control 制御列を追加する時に true # @return [ActiveSupport::SafeBuffer] ラベルの行 def labels(model, array, add_control: false) content_tag :tr do t_ars(model, array).each do |w| concat(content_tag :th, w) end if add_control concat(content_tag :th, I18n.t("common.control")) end end end
おわりに
列の名前は locales
の models/ja.yml
から取得します。モデル自体にその値がなくても、この yml 内にキーの名前があれば表示されます。これによって、ページごとに日本語表記が揺れる問題も回避できますね。