Reputation: 13195
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?
Upvotes: 2
Views: 2298
Reputation: 6025
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
Upvotes: 7
Reputation: 54882
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
Upvotes: 0