Model.errorsを view で表示する際にハマったので同じ気持の人が減ることを祈って
調べたことをまとめます。
今回やろうとしたこと。
Itemモデルの登録formでのvalid結果をviewに表示。
表示の際にエラーメッセージはi18nを用いて日本語化する。
ItemモデルはDraftという名前空間に定義している。
ハマったこと
変換されない。(結論から言うと勘違いです。)
結論
<% @item.errors.full_messages.each do |msg| %>
<ul class="list">
<li><%= msg %></i>
</ul>
<% end %>
ja:
activerecord:
attributes:
draft/item:
item_name: 商品名
上記のように設定し、Model.errors.full_messageを使用すると、
i18nで変換されたカラム名(attribute)が取得できる。
名前空間を指定する場合は
draft/item:
のように、スラッシュ区切りで指定する。
調べられた事。
途中色々とつまずいた為、
足りない箇所については指摘していただけると幸いです。
勘違い
まず、Model.errors.full_messages ではなく、
Model.errors.messagesを使用していました。
messages には以下のようにハッシュが入っています。
@messages={:item_name=>["を入力してください"]}
このハッシュのkeyである、item_name が変換されないと困っていました。(アホ)
どのように変換されるのか。
変換される箇所、メソッドは以下です。
def human_attribute_name(attribute, options = {})
略
end
上記メソッドが、full_messagesメソッドから辿ると呼ばれています。
def full_messages
map { |attribute, message| full_message(attribute, message) }
end
def full_message(attribute, message)
return message if attribute == :base
attr_name = attribute.to_s.tr('.', '_').humanize
attr_name = @base.class.human_attribute_name(attribute, default: attr_name)
I18n.t(:"errors.format", {
default: "%{attribute} %{message}",
attribute: attr_name,
message: message
})
end
これにより、full_messagesメソッドによって返却されるエラーメッセージは、
i18nで変換した結果が取得されます。
うまく思い通りに変換されない場合の対処法
yamlの記述の仕方がわからない等(今回でいうと名前空間に定義したモデルだとyamlの書き方が変わる)
場合に、どのように記述すればよいか調べる。
今回の場合では、human_attribute_name
メソッドで、
i18nで取得しようとしているパスと優先順位がわかるため、デバッグすることで確認します。
:"#{attributes_scope}.#{klass.model_name.i18n_key}/#{namespace}.#{attribute}"
上記のように文字列連結で、i18nで取得するパスを作成しているので、
作成された結果をデバッグで見れば確認することが出来ます。
今回は以下のようになっていました。
[:"activerecord.attributes.draft/item.item_name", :"attributes.item_name", "Item name"]
優先順位が高い順番で格納されています。
このようにyamlで記述すればいいことがわかります。
他に変換がうまく行かないものも、
このように、パスを設定している箇所を特定しデバッグすることで確認できます。
その設定している箇所を特定するいい方法はわかりません・・・。
ご存知の方がいましたらアドバイスをお願い致します・・。