Railsでのi18nでymlを使った日本語化手順

Rails Guideのi18nについての記事。ざっと目を通してみる。

http://guides.rubyonrails.org/i18n.html

i18nという名前はiで始まってnで終わる間に18文字あるのが由来。なんかファンキー。

I18nのもっとも重要なAPI

translate # Lookup text translations
localize  # Localize Date and Time objects to local formats

aliasを使って例えば

I18n.t 'store.title'

とかできる。

以下のAttributesを設定して使う。

load_path         # Announce your custom translation files
locale            # Get and set the current locale
default_locale    # Get and set the default locale
exception_handler # Use a different exception_handler
backend           # Use a different backend

Railsでは、標準で全てのconfig/locales以下の.rbファイルと.ymlファイルをattributeのload_pathとして設定されているみたい。

From: /Users/totz/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/activesupport-4.2.3/lib/active_support/lazy_load_hooks.rb @ line 42:

使い方

ここでモデル名や属性名の多言語化についてもりじゅんさんがまとめてくださってます。

http://morizyun.github.io/blog/i18n-english-rails-ruby-many-languages/#7

Rails Guideの4.6.1 Error Message Scopesでエラーメッセージ関連のことがまとめられてます。

たとえばこんなActiveModel::Validations::ClassMethods#validatesが定義されてる場合

class User < ActiveRecord::Base
  validates :name, presence: true
end

このときは:blankがキーとして対応していて、Active Recordはこのキーを名前空間から探してくるのとこと。

ActiveModel::Errors#full_messages prepends the attribute name to the error message using a separator that will be looked up from errors.format (and which defaults to "%{attribute} %{message}").

実際のymlファイルでのコメントより、

# The values :model, :attribute and :value are always available for interpolation

うーん、わかった。ここの:attributeを変更できればなんとかなりそう。...じゃあどうやって変えればいいんだよ!(T ^ T)

と思ってたら以下のような記述が

Thus, in our example it will try the following keys in this order and return the first result:

activerecord.errors.models.user.attributes.name.blank activerecord.errors.models.user.blank activerecord.errors.messages.blank errors.attributes.name.blank errors.messages.blank

この順番に優先されるっぽい。初期のja.ymlだと

下の二つだと、modelsの名前空間ではないのでできないかも。上の方の優先順位の高い、activerecordから始まる名前空間の辞書を定義してみる。

そしてエラーメッセージは、ActiveModel::Errors#generate_messageが作ってるみたいなので、もうソースを見てみる方が早いかなと思ってみてみることに。

ActiveModel::Errorsは以下で定義されてる。

https://github.com/rails/rails/blob/master/activemodel/lib/active_model/errors.rb

L456がクサい。

      defaults << :"errors.attributes.#{attribute}.#{type}"

多分attributeはStringの何者かなんだけど、これはどこで入ってきてるんだ...

自分はこのエラーメッセージで出力されるときのモデルの名前を日本語にしたかった。試しにわざと辞書の対応する場所をなくしてvalidation errorにしてみると、@user.errors.full_messagesの内容を確認すると、

Email translation missing: ja.activerecord.errors.models.pre_registered_user.attributes.email.blank

という内容が入っていた。

結局下記の記事で解決。

http://rails3try.blogspot.jp/2012/01/rails3-i18n.html

モデル名に関しては、

ja:
  activerecord:
    models:
      pre_registered_user: 事前会員
    attributes:
      pre_registered_user:
        email: メールアドレス
        dog_type_description: その他の犬種

みたいに定義すれば、errors.messagesのモデル部分や属性の部分もtranslateしてくれる。