はじめに
Rails Tips の 41 回目です。以前、index
や show
におけるテーブルラベルを記述する labels
ヘルパーを紹介しました。form
の場合には form.label
で自動的に翻訳文字列が描画されます。ただし、validation
などに抵触した場合には、このラベル部分にエラーを表示したいことが多いです。この部分も毎回記述するのは面倒なので、ラベルとエラーを同時に表示するヘルパーである form_label_and_error
ヘルパーを作成しています。
form_label_and_error の使い方
通常は、form、model、属性名を渡します。model にエラーがあった場合にはエラーも表示します。
form_label_and_error f, year, :year 正常時: "<div><label for=\"year_year\">西暦</label></div>" エラー時: "<div><div class=\"field_with_errors\"><label for=\"year_year\">西暦</label></div><br></br><span class=\"error_message\">西暦を入力してください。</span></div>"
add_text を追加すると、追加テキストを記述します。
form_label_and_error f, year, :year, add_text: "空欄不可" 正常時: "<div><label for=\"year_year\">西暦</label><span>空欄不可</span></div>"
form_label_and_error のテスト
上記のパターンをテストしています。
describe "form_label_and_error" do let(:year) { years(:y2019) } let(:lbl) { "<label for=\"year_year\">西暦</label>" } let(:err) { "<span class=\"error_message\">西暦を入力してください。</span>" } it "form_label_and_error で適切なラベルが設定できること" do form_with model: year do |f| expect(helper.form_label_and_error(f, year, :year)).to( eq "<div>#{lbl}</div>") expect(helper.form_label_and_error(f, year, :year, add_text: "add_text")).to( eq "<div>#{lbl}<span>add_text</span></div>") year.year = nil year.save expect(helper.form_label_and_error(f, year, :year)).to( eq "<div><div class=\"field_with_errors\">#{lbl}</div><br></br>#{err}</div>") end end
form_label_and_error の実装
form_label_and_error のラベルの翻訳は form.label とするだけです。エラーがあった場合には、自動的に field_with_errors
class は自動設定されます。ただし、メッセージは自動的には表示されないので、エラーが存在した場合には追加で表示をするようにしています。
# @param [form] form # @param [Object] model # @param [Symbol] symbol # @param [String, nil] add_text # @return [Temple::HTML::SafeString] form 用の label # @note form_label_and_error def form_label_and_error(form, model, symbol, add_text: nil) content_tag :div do concat form.label symbol if add_text concat content_tag(:span, add_text) end if (error_messages = model.errors.full_messages_for(symbol)).present? concat content_tag(:br) concat content_tag(:span, error_messages.join(", "), class: "error_message") end end end
おわりに
こちらもほぼ定型的な繰り返しになるので、このようなヘルパーで記述量が減るのは嬉しいと思います。これまでエラーメッセージの描画をサボっていたのですが、このヘルパーに書き換えるだけでエラー表示も可能になるので、少しずつ修正しているところです。