Fix: load :en fallback translations if the I18n backend discarded them [Fix #2987]#3275
Open
augustocbx wants to merge 1 commit into
Open
Conversation
When an application restricts I18n.available_locales to a list that does not include :en (e.g. `I18n.available_locales = [:de]`), the i18n backend discards faker's :en translations when it initializes. Faker's :en fallback in `translate` then raises I18n::MissingTranslationData even though the key exists in faker's :en locale files: disabling enforce_available_locales at lookup time cannot restore data that was never stored. Now, when the :en fallback lookup fails and the backend has no faker :en data, load faker's :en locale files into the backend and retry. This loads only the :en files (not all locales), does not modify I18n.available_locales or any already-stored translations, and runs at most once since the data stays stored afterwards. Translations genuinely missing from :en still raise as before.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation / Background
Fixes #2987
When an application restricts
I18n.available_localesto a list that does not include:en(e.g.I18n.available_locales = [:de]), calling a generator whose key is missing in the current locale raises:Root cause: the i18n backend (
I18n::Backend::Simple#store_translations) silently discards translations for locales that are not inI18n.available_localeswhen it initializes. So faker's:endata is never stored, and the:enfallback inFaker::Base.translatefails: wrapping the lookup indisable_enforce_available_localescannot help, because it only affects the lookup — the data was already dropped at load time. This is the line @thdaraujo suspected wasn't working as expected in the issue discussion.Solution: when the
:enfallback lookup fails and the backend has no faker:endata (I18n.exists?('faker', :en)is false), load faker's:enlocale files viaI18n.backend.load_translationsand retry. Properties of this approach::enfiles — it does not pull in all ~60 locales the way theI18n.reload!workarounds from the issue thread do.I18n.reload!, which would drop translations an app stored at runtime), and it does not touchI18n.available_localesorenforce_available_locales.I18n.exists?('faker', :en)is true, so subsequent calls never hit this path again.:enstill raiseI18n::MissingTranslationDataas before (existing tests cover this).Both
I18n.exists?andload_translationsare part of theI18n::Backend::BaseAPI and are available in i18n >= 1.8.11 (the gemspec minimum), including theChainbackend.Additional information
Console output running the reproduction script from the issue against this branch:
Before:
After:
The regression test reproduces the issue scenario (it fails with
I18n::MissingTranslationData: Translation missing: en.faker.company.buzzwordswithout the fix). Note the pre-existingtest_translation_fallback_without_en_in_available_localesdid not catch this because it removes:enafter the backend has already initialized and stored the:endata; the bug only manifests when the backend initializes while:enis excluded, hence theI18n.reload!in the new test.Full suite + RuboCop pass locally:
bundle exec rake→ 2180 tests, 0 failures, 0 errors; 576 files inspected, no offenses.Checklist
[Fix #issue-number]