7
votes

Anyone has some tips as how to translate model associations in Rails?

For example: I have a Person model, which can have many Phone. However, a Person needs to have at least one Phone. I'm not able to translate that validation. The best I could do was this:

validates_presence_of :phones, :message => "At least one phone is required."

And on my YAML, I replaced this line to omit the %{attribute}:

format: ! '%{message}'

This way only my message is displayed, and I avoid the un-translated field name to be displayed.

This is causing me a lot of headache, because some gems simply don't allow me to pass :message => "something describing the error", so I wanted to configure all the error messages through my YAML.

Also, with some models I'm able to translate their attributes, while with others I'm not. For example:

activerecord:  
  attributes:
    additional_info:
      account_manager: "Manager"

This works. I can see on my form "Manager". However, when this field has an error, Rails will display it as "Additional info account manager can't be blank".

I tried this:

activerecord:          
  errors:
    models:
      additional_info:
        attributes:
          account_manager: "Manager"

But no luck.

I did read the docs, but no clue on why it's happening.

2

2 Answers

13
votes

Here are the valid key paths for Rails 4.1:

# Basic Attribute on Model
activerecord:
  attributes:
    #{model_class.model_name.i18n_key}:
      #{attribute_name}:
        "Localized Value"

# Attribute on Nested Model
activerecord:
  attributes:
    #{model_class.model_name.i18n_key}/#{association_name}:
      #{attribute_name}:
        "Localized Value"
    #{association_name}:
      #{attribute_name}:
        "Fallback Localized Value"

So, given this model (which has the i18n_key of :person):

class Person
  has_many :friends
end

You'd have these locale definitions:

activerecord:
  attributes:
    person:
      first_name:
        "My Name"
    person/friends:
      first_name:
        "My Friend's Name"
    friends:
      first_name:
        "A Friend's Name"

If your model is a namespace, such as:

class MyApp::Person
  has_many :friends
end

the i18n_key becomes :my_app/person and your / key starts to wear out:

activerecord:
  attributes:
    my_app/person:
      first_name:
        "My Name"
    my_app/person/friends:
      first_name:
        "My Friend's Name"
    friends:
      first_name:
        "A Friend's Name"
11
votes

Rails 3.2 has changed this behavior. The way I've posted before is deprecated.

Now, in order to translate associations, there is the need to add a slash (instead of nesting everything). So instead of this:

    activerecord:
      attributes:
        person:
          additional_info:
            account_manager: "Manager"

The correct now is:

    activerecord:
      attributes:
        person:
          additional_info/account_manager: "Manager"

Also, I figured out that has_many associations are being translated differently from that. If you want to translate those, the following example may help:

    activerecord:
      attributes:
         emails:
           address: "E-mail field"

Instead of the model name, like I did above, you need to pass the association name, in this case emails.

Check this comment and pull request for more info:

https://github.com/rails/rails/commit/c19bd4f88ea5cf56b2bc8ac0b97f59c5c89dbff7#commitcomment-619858

https://github.com/rails/rails/pull/3859