Translate Rails model association - not working - ruby-on-rails

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.

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"

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

Related

Error messages in nested attribute

I've three models called Account,User and AccountPermission.
I'm creating the Account via AccountPermission while creating user.
However, If a problem occurs related with Account :name, the system throws something like that below.
Account permissions account name has already been taken
So, I just need to fix this error message.
I've tried to add a message attribute to my validation. It is just appending to actual message.
I've also tried locale thing. Still just appending
en:
activerecord:
errors:
models:
account:
attributes:
name:
taken: 'bla bla'
As far as I see in ActiveModel. This message's structure comes from below
locale/en.yml in ActiveModel
en:
errors:
format: "%{attribute} %{message}"
So, Is there any way edit this message painless ? If I even delete the model name, It's enough.
Error message is concatenated from the error itself and the attribute name, which is account_permissions/account.name in the provided error.
You can add locale for your attribute names like so:
en:
activerecord:
attributes:
account: # this is model name
name: "Name"
or
en:
activerecord:
attributes:
account_permissions/account:
name: "Account name"

Translating model attribute name

I'm trying to translate an attribute name in Rails (3.2) to something more human readable, specifically for error messages, but I keep getting the original DB column name. Here's my en.yml file
activerecord:
attributes:
user:
encrypted_password: "Password"
errors:
models:
user:
attributes:
encrypted_password:
blank: "can't be blank"
I also tried this as seen here
activerecord:
models:
user: Dude
attributes:
user:
encrypted_password: "Password"
The interesting thing is that the second translation (for errors) works, but not the first. What am I missing ?

Trouble on using the i18n gem with "resources of resources"

I am using Ruby on Rails 3.1 and I would like to know how to correctly handle internationalization related to "resources of resources". That is, ...
... in my config/routes.rb file I have:
resources :users do
resource :account
end
... in my app/models/users/account.rb file I have:
class Users::Account < ActiveRecord::Base
validates :firstname,
:presence => true
...
end
... in my config/locales/models/user/account/en.yml file I have:
en:
activerecord:
errors:
messages:
presence: "custom presence message - english"
... in my config/locales/models/user/account/it.yml file I have:
it:
activerecord:
errors:
messages:
presence: "custom presence message - italian"
The above code doesn't display in front end the "custom presence message" (it still displays the default RoR presence message: can not be blank). Furthermore if in my app/models/users/account.rb file I use:
class Users::Account < ActiveRecord::Base
validates :firstname,
:presence => { :message => t(:presence) } # Here I try to use the i18n helper method
...
end
I get the following error:
NoMethodError (undefined method `t' for #<Class:0x000001075bbc80>)
Why I get the NoMethodError?
Is the problem related to how I am organizing in directories my locale files? At this time (as stated in the official RoR guide) my file system is:
config/locales/defaults/en.yml
config/locales/defaults/it.yml
config/locales/models/user/en.yml
config/locales/models/user/it.yml
config/locales/models/user/account/en.yml
config/locales/models/user/account/it.yml
In few words, I would like to display my "custom presence message" only on validating "resources of resources" kind of Users::Account. How can I do that?
I also tried to state the following code in the config/locales/models/user/account/en.yml file
en:
activerecord:
errors:
models:
user:
account:
attributes:
firstname:
blank: "custom presence message - english"
but it doesn't work. Anyway the following works but I need different translations for different attributes (as I tried to state in the previous code example):
en:
activerecord:
errors:
messages:
blank: "custom presence message - english"
ok, due to this: https://github.com/rails/rails/issues/1402 last comment nested model look-up is removed
so try maybe something like
activerecord:
errors:
models:
users:
account:
attributes:
first_name:
blank: "You should fill up first name field to complete that"
and change inside :message hash to
I18n.t(:"activerecord.errors.models.users.account.attributes.first_name.blank")
and try avoid nested models ;-)
update:
after some debuging this will work:
activerecord:
errors:
models:
"users/account":
attributes:
first_name:
blank: "You should fill up first name field to complete that"

Rails 3 Customer Error message

I'm trying to do something very simple. I have a validates presence of in rails 3:
validates_presence_of [:first_nm]
When this fires, it gives the following crappy message:
"first nm cannot be blank"
I want to override the error message to give a friendly field name for "first nm"
"Please fill out your First Name"
I have seen all kinds of plugins, localization, humanized attributes tutorials, but these don't seem to work or are outdated. Is there no simple way to do this in Rails 3?
For localization, i've tried this:
# Sample localization file for English. Add more files in this directory for other locales.
# See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
en:
activerecord:
errors:
messages:
taken: "has already been taken"
record_invalid: "Validation failed: %{errors}"
models:
customer:
blank: "This is a custom blank message for %{model}: %{attribute}"
attributes:
first_nm:
blank: "This is a custom blank message for first name"
Alas, no luck. My error message did not change.
On thing that might be related. I'm not inheriting from ActiveRecord, because this object is getting saved via soap, not database. Instead, I have the following:
class Customer
extend ActiveModel::Naming
include ActiveModel::Conversion
include ActiveModel::Validations
end
Have you seen this page on ActiveRecord localization? It seems to be for Rails 3. I can't test it right now, but by the document it seems you can do:
models.user.attributes.first_nm.blank = "Please fill out your First Name"

Adding translations for the models in the Rails application

I am new to ROR. I am trying add translations to my application. I have added translations for the controllers.
Where to add translations for models as i am not having any /config/locales -> models folder ->en.yml file .
In the model i am having lines like
validates_presence_of :name, :message => "Name cannot be blank!"
If i want to add translations for the message "Name cannot be blank", shall i put directly as like
validates_presence_of :name, :message => I18n.t(str_name_notblank)
Please give suggestions
To add translations to your models you just need to put them under activerecord->models and activerecord->attributes. Here's an example in polish:
pl:
activerecord:
models:
patient: "Pacjent"
attributes:
patient:
first_name: "Imię"
last_name: "Nazwisko"
address: "Ulica"
postal_code: "Kod"
city: "Miejscowość"
Note that the attributes element is not under the patient element, but actually includes it again. I found this after some debugging and it actually worked for me. The Rails I18n guide suggested a different structure, but it didn't work.
The best way to translate standard Rails messages (like the ones for validation) is to download the correct translation file from Sven Fuchs' Rails Locale Data Repository (rails-18n) and put it into your config/locales folder (you can change the name). Then you'd remove your :message string and just use the standard messages, but translated to your liking.

Resources