Excerpt from my config/locales/models/de.yml:
de:
activerecord:
attributes:
guestbook:
message: Nachricht
The database exactly is the meaning of messages, but the message of the validation error instead of "Nachricht" written "Messages". What's the problem?
Make sure you have setup in config/application.rb the following:
config.i18n.default_locale = :de
Related
I have a ruby on rails application. I have spanish and english support in my application. However, I get a translation missing exception in case spanish mode.
I have the following model:
class Company < ApplicationRecord
validates :name, length: { in: 5..15, message: :bad_name }
end
en.yml
en:
activerecord:
errors:
models:
company:
attributes:
name:
bad_name: 'message in english'
sp.yml
sp:
activerecord:
errors:
models:
company:
attributes:
name:
bad_name: 'message in spanish'
Just in case the error when I open the application in english. I get the "message in english" message and that's ok.
On the other hand, when I open and test it in spanish, I get the following error.
ActiveRecord::RecordInvalid:
translation missing: sp.activerecord.errors.messages.record_invalid
I can't see what I'm missing,
Any suggestions,
Thanks.
Are other translations work in this file?
Try to rename sp.yml to es.yml, because this is the iso-code for "espanol".
Also try to include a message for activerecord.errors.messages.record_invalid in your spansih file. will this be displayed?
Actually, to use Spanish within your locale you would need to set I18n.locale = :es. I think you mixed up your locales. The correct language file should be named es.yml and look like:
es:
activerecord:
errors:
models:
company:
attributes:
name:
bad_name: 'message in spanish'
I have a non-AR model, which I use for a form/composition object.
There are lots input fields, which I collect in order to do some data manipulation inside AR transaction.
I use I18n for internationalization.
yml:
pl:
activemodel:
attributes:
catalog/checkout:
name: ImiÄ™
form:
= f.input :name,
required: true,
label: I18n.t(:'.activemodel.attributes.catalog/checkout.name')
The issue is that in development and production modes (locally) I see the input having proper label taken from config/locales, but on production server it says
"translation missing: pl.activemodel.attributes.catalog/checkout.name"
It happens exclusively with this non-AR model - everywhere else I18n works perfectly fine.
Any thoughts?
EDIT
Logged into the production server's console:
I18n.reload!
#=> nil
I18n.t(:'.activemodel').keys
#=> [:errors, :attributes] # attributes is what wee need
But
I18n.t(:'.activemodel.attributes')
#=> "translation missing: pl.activemodel.attributes"
Wth?...
EDIT #2
I have to notice, that having
pl:
activemodel:
attributes:
catalog/checkout:
errors:
models:
catalog/checkout:
attributes:
errors section works as expected, problems are only with activemodel.attributes
In my locale file, there is the following translation:
de:
activerecord:
errors:
models:
user:
attributes:
email:
taken: "Die E-Mail Adresse wird bereits benutzt."
When i open the desired page in my browser, the error message looks like the following:
Email Die E-Mail Adresse wird bereits benutzt.
So does anybody know why there is another "Email" in front of the translated string?
The correct yml structure should be:
de:
activerecord:
models:
user: Dude
attributes:
user:
email: "mail"
errors:
template:
header:
one: "1 error prohibited this %{model} from being saved"
other: "%{count} errors prohibited this %{model} from being saved"
body: "There were problems with the following fields:"
errors:
format: ! '%{attribute} %{message}'
messages:
taken: "Email Die E-Mail Adresse wird bereits benutzt."
Note that there are two "errors" keys, one inside activerecord and another one outside. Use the later for validation messages.
You could get a more full detailed translation file from https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/en.yml
You might find the devise translation file at https://github.com/mcasimir/devise-i18n-views/blob/master/locales/en.yml
For my projects, I usually have several translation files for each language:
rails.en.yml: messages used by rails (inspired by the svenfuchs file)
devise.en.yml: messages related to authentication (from the devise project itself)
en.yml: messages I create on my views that doesn't belong to other gems (gems like "simple_form" usually have also their own file)
Edit
From the Rails Internationalization guide, validation messages will be searched in this order:
activerecord.errors.models.user.attributes.name.blank
activerecord.errors.models.user.blank
activerecord.errors.messages.blank
errors.attributes.name.blank
errors.messages.blank
So it's correct to use what you posted on the question:
de:
activerecord:
errors:
models:
user:
attributes:
email:
taken: "http://guides.rubyonrails.org/i18n.html#translations-for-active-record-models"
We often stumble over untranslated model attributes in our application. They most often come because an attribute was renamed or something like this.
It would be really helpful to have I18n raise an error when Model.human_attribute_name :field doesn't find a translation. Is there a way to achieve this?
Update:
It seems there's some other problem. here are my I18n settings:
I18n.enforce_available_locales = false
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
config.i18n.default_locale = 'de-CH'
config.i18n.available_locales = ['de', 'de-CH', 'en']
config.i18n.locale = 'de-CH'
config.i18n.fallbacks = {'de-CH' => 'de', 'en-GB' => 'en'}
I can't set fallbacks = false because I want missing translations of de-CH to gracefully delegate to de, which in general seems to work fine. But for my state machine attribute human_to_state method it doesn't seem to work. Here's the view code causing the problem:
= f.input :state_event, collection: f.object.state_transitions,
label_method: :human_to_name # This causes the problem!
This is printed out as "State event" in the view, and when I add the following I18n key, it's translated successfully to "Status":
de:
mongoid:
attributes:
activity:
state_event: Status
So there really is a missing translation, but I18n doesn't complain in any way. I also tried to catch the exception using a custom exception handler, but this doesn't seem to be raised:
I18n.exception_handler = lambda do |exception, locale, key, options|
binding.pry # This is never reached!
end
Any idea what's going on? Is it a problem with state machine?
The problem lies in the fact that human_attribute_name falls back to
defaults << attribute.to_s.humanize
when nothing else found. In other words, human_attribute_name will never raise an error.
I "fixed" this by overriding human_attribute_name, patching the above mentioned line:
(put this in an initializer)
require 'active_support/core_ext/hash/reverse_merge'
module ActiveModel
module Translation
include ActiveModel::Naming
def human_attribute_name(attribute, options = {})
defaults = lookup_ancestors.map do |klass|
[:"#{self.i18n_scope}.attributes.#{klass.model_name.i18n_key}.#{attribute}",
:"#{self.i18n_scope}.attributes.#{klass.model_name.i18n_key.to_s.tr('.', '/')}.#{attribute}"]
end.flatten
defaults << :"attributes.#{attribute}"
defaults << options.delete(:default) if options[:default]
defaults << attribute.to_s.humanize if Rails.env.production? # Monkey patch
options.reverse_merge! :count => 1, :default => defaults
I18n.translate(defaults.shift, options)
end
end
end
Possible duplicate of : How to enable Rails I18n translation errors in views?
The accepted answer is:
config.i18n.fallbacks = false
#BettySt 's answer is pretty cool too, you should take a look at her solution.
Doc about how to handle I18n translation errors:
http://guides.rubyonrails.org/i18n.html#using-different-exception-handlers
I wanted to set a custom error message for when an email was already taken so I edited the config/locales/en.yml file. It looked like this:
en:
activerecord:
models:
user:
email:
taken: "already being used"
When I submit the form with email in it, I get this error:
translation data {:email=>{:taken=>"already being used"}} can not be used with :count => 1
I've only just started looking into i18n so this may be a really simple mistake but I can't find an answer.
Try:
en:
activerecord:
errors:
models:
user:
attributes:
email:
taken: "already being used"
See section 5.1.1 in Rails Guide.
Hope this helps!