From 8bb0ed7360c53d523b75d6758ff960da6699acff Mon Sep 17 00:00:00 2001 From: Augusto Xavier Date: Wed, 10 Jun 2026 16:04:41 -0300 Subject: [PATCH] Fix: load :en translations if I18n discarded them [Fix #2987] 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. --- lib/faker.rb | 9 +++++++++ test/test_locale.rb | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/lib/faker.rb b/lib/faker.rb index a5d7d472b9..9049371476 100644 --- a/lib/faker.rb +++ b/lib/faker.rb @@ -186,6 +186,15 @@ def translate(*args, **opts) # in en either, then it will raise again. disable_enforce_available_locales do I18n.translate(*args, **opts) + rescue I18n::MissingTranslationData + # I18n discards translations for locales that are not in + # I18n.available_locales when it initializes. If the :en + # translations were discarded, load them and try once more. + raise if I18n.exists?('faker', :en) + + en_files = Dir[::File.join(__dir__, 'locales', 'en.yml'), ::File.join(__dir__, 'locales', 'en', '**/*.yml')] + I18n.backend.load_translations(en_files) + I18n.translate(*args, **opts) end end diff --git a/test/test_locale.rb b/test/test_locale.rb index 4e2f0e037d..f59ffb6b96 100644 --- a/test/test_locale.rb +++ b/test/test_locale.rb @@ -51,6 +51,19 @@ def test_translation_fallback_without_en_in_available_locales I18n.available_locales += [:en] end + # https://github.com/faker-ruby/faker/issues/2987 + def test_translation_fallback_when_i18n_initialized_without_en_in_available_locales + old_available_locales = I18n.available_locales + I18n.available_locales = [:de] + I18n.reload! # force I18n to discard the :en translations + Faker::Config.locale = :de + + assert_kind_of String, Faker::Company.catch_phrase + ensure + I18n.available_locales = old_available_locales + I18n.reload! + end + def test_with_locale_does_not_fail_without_the_locale_in_available_locales I18n.available_locales -= [:en]