Skip to content

FEATURE: Localization fallbacks (server-side)#9

Open
ShashankFC wants to merge 1 commit into
localization-system-prefrom
localization-system-post
Open

FEATURE: Localization fallbacks (server-side)#9
ShashankFC wants to merge 1 commit into
localization-system-prefrom
localization-system-post

Conversation

@ShashankFC

@ShashankFC ShashankFC commented Jan 5, 2026

Copy link
Copy Markdown
Collaborator

Test 9

Summary by CodeRabbit

Release Notes

  • Refactor

    • Restructured internationalization fallback system with optimized on-demand locale loading for improved efficiency.
    • Enhanced locale fallback resolution to intelligently cascade through requested language, site default, and English.
    • Consolidated locale initialization logic for better maintainability.
  • Chore

    • Removed deprecated pluralization backend integration from environment configurations.

✏️ Tip: You can customize this high-level summary in your review settings.


Replicated from ai-code-review-evaluation/discourse-coderabbit#9

The FallbackLocaleList object tells I18n::Backend::Fallbacks what order the
languages should be attempted in. Because of the translate_accelerator patch,
the SiteSetting.default_locale is *not* guaranteed to be fully loaded after the
server starts, so a call to ensure_loaded! is added after the locale is set for
the current user.

The declarations of config.i18n.fallbacks = true in the environment files were
actually garbage, because the I18n.default_locale was
SiteSetting.default_locale, so there was nothing to fall back to. *derp*
@ShashankFC

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jan 13, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jan 13, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The changes refactor I18n locale fallback handling by introducing a custom FallbackLocaleList class to compute fallback chains dynamically, adding on-demand locale loading via ensure_loaded! methods, and removing explicit fallback and pluralization configuration from environment files.

Changes

Cohort / File(s) Summary
Configuration Removal
config/environments/production.rb, config/environments/profile.rb, config/cloud/cloud66/files/production.rb, config/initializers/pluralization.rb
Removes static I18n fallback configuration and explicit pluralization backend initialization from environment-specific and general initializers.
Fallback Mechanism Implementation
config/initializers/i18n.rb
Introduces new FallbackLocaleList class (Hash subclass) that computes fallback locale chains as [requested_locale, site_default_locale, :en] with uniqueness and nil handling. Includes ensure_loaded! method for on-demand locale loading and replaces default I18n.fallbacks instance.
On-Demand Locale Loading
lib/freedom_patches/translate_accelerator.rb
Adds ensure_loaded!(locale) class method to I18n module for lazy locale loading, tracking previously loaded locales to avoid redundant loads.
Controller Integration
app/controllers/application_controller.rb
Integrates locale fallback loading by calling I18n.fallbacks.ensure_loaded! within set_locale method after locale assignment.

Sequence Diagram

sequenceDiagram
    participant Controller as Request Handler
    participant Fallback as FallbackLocaleList
    participant I18n as I18n Module
    participant Loader as Locale Loader

    Controller->>Fallback: ensure_loaded!()
    Fallback->>Fallback: [locale, default_locale, :en]
    Fallback->>I18n: ensure_loaded!(computed_locales)
    I18n->>I18n: `@loaded_locales` ||= Set.new
    alt Locale not in `@loaded_locales`
        I18n->>Loader: load_locale(locale)
        Loader-->>I18n: Locale loaded
        I18n->>I18n: Add to `@loaded_locales`
    end
    I18n-->>Fallback: Complete
    Fallback-->>Controller: Ready for translation
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A fallback chain now springs to life,
With locales loaded on demand, no strife,
From :en to custom, just what's required,
The I18n translation flow, now inspired! 🌍✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'FEATURE: Localization fallbacks (server-side)' accurately describes the main change in the pull request, which implements server-side localization fallbacks through a custom FallbackLocaleList object.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

@ShashankFC

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jan 13, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
config/initializers/i18n.rb (3)

3-5: Prefer direct include over send(:include, ...).

Per static analysis (RuboCop), Ruby 2.1+ allows calling include directly on modules.

♻️ Suggested refactor
 # Include pluralization module
 require 'i18n/backend/pluralization'
-I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
+I18n::Backend::Simple.include(I18n::Backend::Pluralization)

7-9: Same refactor applies here.

♻️ Suggested refactor
 # Include fallbacks module
 require 'i18n/backend/fallbacks'
-I18n.backend.class.send(:include, I18n::Backend::Fallbacks)
+I18n.backend.class.include(I18n::Backend::Fallbacks)

12-18: Consider defensive nil handling for SiteSetting.default_locale.

If SiteSetting.default_locale returns nil during early initialization or edge cases, calling .to_sym will raise NoMethodError. The compact on line 17 removes nils from the array but executes after to_sym.

🛡️ Suggested defensive change
 class FallbackLocaleList < Hash
   def [](locale)
     # user locale, site locale, english
     # TODO - this can be extended to be per-language for a better user experience
     # (e.g. fallback zh_TW to zh_CN / vice versa)
-    [locale, SiteSetting.default_locale.to_sym, :en].uniq.compact
+    [locale, SiteSetting.default_locale&.to_sym, :en].uniq.compact
   end
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 728845d and ecfa17b.

📒 Files selected for processing (7)
  • app/controllers/application_controller.rb
  • config/cloud/cloud66/files/production.rb
  • config/environments/production.rb
  • config/environments/profile.rb
  • config/initializers/i18n.rb
  • config/initializers/pluralization.rb
  • lib/freedom_patches/translate_accelerator.rb
💤 Files with no reviewable changes (4)
  • config/environments/profile.rb
  • config/cloud/cloud66/files/production.rb
  • config/environments/production.rb
  • config/initializers/pluralization.rb
🧰 Additional context used
🧬 Code graph analysis (2)
app/controllers/application_controller.rb (2)
config/initializers/i18n.rb (1)
  • ensure_loaded! (20-22)
lib/freedom_patches/translate_accelerator.rb (1)
  • ensure_loaded! (62-65)
lib/freedom_patches/translate_accelerator.rb (1)
config/initializers/i18n.rb (3)
  • ensure_loaded! (20-22)
  • locale (12-23)
  • locale (13-18)
🪛 Brakeman (7.1.1)
app/controllers/application_controller.rb

[medium] protect_from_forgery should be configured with with: :exception
Type: Cross-Site Request Forgery
Confidence: Medium
More info: https://brakemanscanner.org/docs/warning_types/cross-site_request_forgery/

(Cross-Site Request Forgery)

🪛 RuboCop (1.82.1)
config/initializers/i18n.rb

[warning] 5-5: Use include I18n::Backend::Pluralization instead of send(:include, I18n::Backend::Pluralization).

(Lint/SendWithMixinArgument)

🔇 Additional comments (3)
lib/freedom_patches/translate_accelerator.rb (1)

62-65: LGTM!

The ensure_loaded! method follows the same pattern as the existing translate method (line 68), with load_locale providing thread-safe double-checking internally via LOAD_MUTEX. This provides a clean public API for on-demand locale loading.

config/initializers/i18n.rb (1)

20-24: LGTM!

The ensure_loaded! method correctly iterates over the computed fallback chain and loads each locale via the patched I18n.ensure_loaded!. The assignment at line 24 properly wires up the custom fallback behavior.

app/controllers/application_controller.rb (1)

152-160: LGTM!

The ensure_loaded! call is correctly placed after determining the locale, ensuring all fallback locales (user locale → site default → English) are loaded before any translations occur in the request lifecycle. This aligns well with the on-demand loading strategy introduced in this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants