Translations returned as hash when model-inflection has nested keys
Closed this issue · 17 comments
Pre 1.7.1 State
Related: #510
Our translations look something like:
activerecord:
models:
moose:
one: Moose
other: Moosen
moose_types:
big: Big ol moose
...
What I expected to happen
Moose.model_name.human(count: 2) #=> 'Moosen'
What actually happened
Moose.model_name.human(count: 2) #=> Hash
(Actually, I think this makes more sense!)
Versions of i18n, rails, and anything else you think is necessary
- ruby 2.6
- rails 5.2
- i18n 1.8.1
So, it seems that our application wasn't really using model-translations idiomatically. The usage are not attributes, so they kinda got shoved in below the model-key.
If that pattern is considered wrong, this is a good forcing function towards convention (maybe it can be added to docs?). If it's an acceptable pattern, I would consider this a regression.
Happy to provide more detail/insight if required, but this seems pretty straightforward.
The latest release of i18n is 1.8.2 and contains a fix for this issue: https://github.com/ruby-i18n/i18n/releases/tag/v1.8.2.
You’re saying you’re using 1.8.1.
@radar sounds good.
Would you say that the pattern of nesting attributes within a key meant for inflection is bad?
Likely yes. It shouldn’t effect the performance of the library. It’s hash-based, so it’s only picking out the relevant keys as you need them. It’ll ignore other keys.
That's kind of what I'm wondering...it may have been a regression, but if it forces better patterns, I'm for it. 👍
In either case, thanks for being so responsive and helpful!
❤️
@radar can confirm this still caused the same issues in 1.8.2.
I am unable to reproduce this in a new Rails application. Please provide an application that reliably reproduces the issue with any version of Rails, and I18n 1.8.2.
@chevinbrown Unfortunately, there is still in error in 1.8.2
When you use the following locale file content:
en:
model:
one: Single
other: Multiple
nested:
broken: Broken
Then you see the following situation:
> I18n.t('model', count: 1)
{:one=>"Single", :other=>"Multiple", :nested=>{:broken=>"Broken"}}
When there is no nested information, so the nested
part from the YAML is not there, then everything works.
en:
model:
one: Single
other: Multiple
> I18n.t('model', count: 1)
Multiple
Do you want to have another issue for this?
It’s a simple request, really.
This application is clearly using 1.8.1: https://github.com/mobilutz/ruby-i18n-issue-514/blob/master/Gemfile.lock#L67.
Please upgrade to 1.8.2.
bundle update i18n
I will push I18n upgrade as well.
But it does not help:
irb(main):001:0> I18n.t('activerecord.models.broken_model', count: 1)
=> {:one=>"My Model Translation", :other=>"My Models Translation", :some_other_key=>{:key=>"Value"}}
irb(main):002:0> I18n::VERSION
=> "1.8.2"
I am able to reproduce this issue in 1.8.2, however I know of the fix.
The issue lies here:
https://github.com/ruby-i18n/i18n/blob/master/lib/i18n/backend/pluralization.rb#L34
When this line attempts to find the pluralizer logic in your application, the translation is missing and so this returns a String:
=> "translation missing: en.i18n.plural.rule"
I18n by default does not include pluralization rules because there are way too many languages, and not every application needs pluralization rules for every language.
To define the pluralization rules, we have a separate gem called rails-i18n
. If you add this gem to your Gemfile, your code will work as you want it to -- as long as you're using i18n 1.8.2 too.
@radar Thanks for that information. I will definately add the additional gem to our app, to see if that solves the problem.
Can you maybe enlighten me, why version 1.7.1 (a patch version) lead to this error?
Check out the changelog: https://github.com/ruby-i18n/i18n/releases/tag/v1.7.1
Count issue was introduced in 1.7.0 and to PATCH that issue I released 1.7.1. I don’t see a problem here.
This issue still exists in cases where the user is not using Backend::Pluralization.pluralize
, but instead is using the default Backend::Base.pluralize
.
The issue was introduced in #503 in both Backend::Base
and Backend::Pluralization
, but only reverted in Backend::Pluralization
, leaving the issue in Backend::Base
.
Reproducing test case (add it to test/backend/simple_test.rb
)
test "simple backend translate: nested keys within pluralization context" do
store_translations(:en,
:stars => {
one: "%{count} star",
other: "%{count} stars",
special: {
one: "%{count} special star",
other: "%{count} special stars",
}
}
)
assert_equal "1 star", I18n.t('stars', count: 1)
end
I18nBackendSimpleTest#test_simple_backend_translate:_nested_pluralization [test/backend/simple_test.rb:77]:
--- expected
+++ actual
@@ -1 +1 @@
-"1 star"
+{:one=>"%{count} star", :other=>"%{count} stars", :special=>{:one=>"%{count} special star", :other=>"%{count} special star"}}