I18n uses YAML files to store translations, however when using an integer as a map key, the translation is then missing when referenced. This may be unexpected at first, but below describes the translation process, and why it is happening.
en:
1:
foo: 'bar'
I18n.translate('1.foo') #=> "translation missing: en.1.foo"
We might have expected 'bar'
I18n.translatecallslookupcallsI18n.normalize_keys(i18n-0.6.1/lib/i18n.rb:255) callsnormalize_key(i18n-0.6.1/lib/i18n.rb:303)
The normalize_key method is shown below:
def normalize_key(key, separator)
normalized_key_cache[separator][key] ||=
case key
when Array
key.map { |k| normalize_key(k, separator) }.flatten
else
keys = key.to_s.split(separator)
keys.delete('')
keys.map! { |k| k.to_sym }
keys
end
end
Note that this calls key.to_s followed by .to_sym. e.g. normalize_key("1.foo", ".") # => [:"1", :foo]
The translation file is loaded in the lookup method at this time with the key preserved in Integer format. However our lookup key is now: key.to_s.to_sym They integer map key is converted to a symbol, however we are now comparing :"1" with "1" and the translation fails because the key is missing.
Even though YAML supports Integers as map keys - use string representations of Integers as map keys when using I18n