Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 5 I18n default_locale and fallback locale

How do I set a fallback locale in Rails 5.2?

Right now it prints ''(blank) for attribute names if not found in locale. I would like it to fallback to :en when that happens.

Rails 5 specific?

# config/application.rb 
config.load_defaults 5.0
config.i18n.default_locale = :nb

run specs and get:

#<ActiveRecord::RecordInvalid: Det oppstod en feil: er allerede i bruk>
see the missing part here:
#<ActiveRecord::RecordInvalid: Det oppstod en feil: [MISSING RECORD NAME] er allerede i bruk>

# switch to 
# config.i18n.default_locale = :en
#<ActiveRecord::RecordInvalid: Validation failed: Report date has already been taken> 

UPDATE:

@Nate got the fallback config correct in his answer below (https://stackoverflow.com/a/53453211/252799)

That wasn't the issue though. The problem, I learned, was in my nb.yml.

  • Experiment 1. Deleting the entire content of nb.yml, leaving just hello world. Works: It prints the attribute (associated record) name.
  • Experiment 2. Replacing our nb.yml with the official Rails nb.yml: https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/nb.yml : Works. I get the helpful norwegian-english message Det oppstod feil: Company må eksistere. Not pretty, but helpful and what I wanted!
  • Experiment 3. Proof. The nb.yml reproduces the problem.

Two approaches

# A: SHOW attribute name
nb: 
  errors:
    format: "%{attribute} %{message}"

# B: HIDE attribute name
nb:
  errors:
    format: "%{message}"

Which leads to another problem.

Approach B: HIDE makes you blind serverside. the specs, logs and console will show Validation Failed: can't be blank but it looks good in UI.

I posted another Q: Simpleform errors without attribute name, but using attribute name in logs, console, specs

like image 712
oma Avatar asked Nov 20 '18 17:11

oma


Video Answer


2 Answers

Rails 5.2 allows you to set config.i18n.fallbacks to control which fallback locale(s) are able to be used. Set it to an array of symbols to control which locales should be used when a translation is not found. When multiple are set, it goes through the array one by one until a transliterate works (or doesn't).

In your case, you'll want the following in your config/application.rb:

config.i18n.default_locale = :nb
config.i18n.fallbacks = [:en]

This way, if a locale is not specified, it uses the :nb locale (your default locale). Then, any time a translate fails in any locale, it will try the :en locale as a fallback.

Note: if none of your fallback locales have a translation for the key you're trying to translate, you'll still get the translation missing error.

For a more complete answer, here's an example with multiple fallbacks. They will be checked in the order specified:

config.i18n.default_locale = :nb
config.i18n.fallbacks = [:en, :es, :de]
like image 113
Nate Avatar answered Oct 18 '22 20:10

Nate


Spree (4.1.5) + spree_i18n (3.3.2) on Rails (6.0.3.1), I wanted the site in Spanish and to fall back to English for missing translations. This is what worked for me:

# config/application.rb

config.after_initialize do
    config.i18n.default_locale = :es
    config.i18n.locale = :en
end
config.i18n.fallbacks = true

The config.after_initialize block is necessary, otherwise it wouldn't work (spree_i18n would mess the locales on initialization). That last config.i18n.fallbacks line is actually not needed since spree_i18n sets it to true on initialization. But I leave it there anyway so I know what is going on (furthermore, spree might stop overriding this in future versions since in development it might be useful not to use fallbacks thus making missing translations more visible).

like image 22
pasqal Avatar answered Oct 18 '22 22:10

pasqal