読者です 読者をやめる 読者になる 読者になる

accepts_nested_attributes_forしたときのi18n

Rails 5.0.2

Railsi18n書くときに、ちょっと複雑になるとYAMLをどう書けばいいかわからなくなる問題。

たぶんソース見るのが一番良い。こことかね。

github.com

のだけど、accepts_nested_attributes_forしたときのi18nの書き方だけまとめておく。

こんな感じのmodelだったとして、

class Parent < ApplicationRecord
  has_many :children
  accepts_nested_attributes_for :children
end

class Child < ApplicationRecord
  belongs_to :parent
  validates :name, presence: true
end

accepts_nested_attributes_forを使って、ParentsController#create / updateから一気にChildの作成/更新までやるとする。

ここで、Child側でValidation Errorが発生したら、当然エラーメッセージを画面に出したい。このとき、i18nをどう書くか。言い換えると、Childname属性を空のままpostされた場合に、@parent.errors.full_messagesの結果が、i18nで「子供の名前を入力してください。」となるようにするにはどうすればいいかという話。

で、結論は、こう。

ja:
  activerecord:
    attributes:
      parent/children:
        name: 子供の名前

辿り方としては、まず、@parent.errorsの中身を見ると、このように子のvalidation errorが格納されていることがわかる。

@details={:"children.name"=>[{:error=>:blank}]}

このchildren.nameの翻訳をどのように探しに行くか、以下のコードを見ると、

github.com

parts     = attribute.to_s.split(".")
attribute = parts.pop
namespace = parts.join("/") unless parts.empty?

この部分で、attributenameが、namespacechildrenが入り、

:"#{attributes_scope}.#{klass.model_name.i18n_key}/#{namespace}.#{attribute}"

これにより、#{attributes_scope}.parent/children.nameという文字列が組み立てられることになるわけ。