Fix crash with no translation for default locale
When we were visiting a page showing the content of a record which uses globalize and our locale was the default one and there was no translation for the default locale, the application was crashing in some places because there are no fallbacks for the default locale. For example, when visiting a legislation process, the line with `CGI.escape(title)` was crashing because `title` was `nil` for the default locale. We've decided to solve this issue by using any available translations as globalize fallbacks instead of showing a 404 error or a translation missing error because these solutions would (we thinkg) either require modifying many places in the application or making the translatable logic even more complex. Initially we tried to add this solution to an initializer, but it must be called after initializing the application so I18n.fallbacks[locale] gets the value defined in config.i18n.fallbacks. Also note the line: fallbacks[locale] = I18n.fallbacks[locale] + I18n.available_locales Doesn't mention `I18n.default_locale` because the method `I18n.fallbacks[locale]` automatically adds the default locale.
This commit is contained in:
@@ -48,6 +48,8 @@ module Consul
|
|||||||
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
|
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
|
||||||
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', 'custom', '**', '*.{rb,yml}')]
|
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', 'custom', '**', '*.{rb,yml}')]
|
||||||
|
|
||||||
|
config.after_initialize { Globalize.set_fallbacks_to_all_available_locales }
|
||||||
|
|
||||||
config.assets.paths << Rails.root.join("app", "assets", "fonts")
|
config.assets.paths << Rails.root.join("app", "assets", "fonts")
|
||||||
|
|
||||||
# Do not swallow errors in after_commit/after_rollback callbacks.
|
# Do not swallow errors in after_commit/after_rollback callbacks.
|
||||||
|
|||||||
@@ -11,3 +11,9 @@ module Globalize
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def Globalize.set_fallbacks_to_all_available_locales
|
||||||
|
Globalize.fallbacks = I18n.available_locales.each_with_object({}) do |locale, fallbacks|
|
||||||
|
fallbacks[locale] = (I18n.fallbacks[locale] + I18n.available_locales).uniq
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
@@ -141,6 +141,14 @@ feature 'Legislation' do
|
|||||||
|
|
||||||
expect(page).to_not have_content("Additional information")
|
expect(page).to_not have_content("Additional information")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
scenario "Shows another translation when the default locale isn't available" do
|
||||||
|
process = create(:legislation_process, title_fr: "Français")
|
||||||
|
process.translations.where(locale: :en).first.destroy
|
||||||
|
|
||||||
|
visit legislation_process_path(process)
|
||||||
|
expect(page).to have_content("Français")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'debate phase' do
|
context 'debate phase' do
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ require 'rails_helper'
|
|||||||
describe AdminNotification do
|
describe AdminNotification do
|
||||||
let(:admin_notification) { build(:admin_notification) }
|
let(:admin_notification) { build(:admin_notification) }
|
||||||
|
|
||||||
|
it_behaves_like "globalizable", :admin_notification
|
||||||
|
|
||||||
it "is valid" do
|
it "is valid" do
|
||||||
expect(admin_notification).to be_valid
|
expect(admin_notification).to be_valid
|
||||||
end
|
end
|
||||||
|
|||||||
56
spec/models/concerns/globalizable.rb
Normal file
56
spec/models/concerns/globalizable.rb
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
require "spec_helper"
|
||||||
|
|
||||||
|
shared_examples_for "globalizable" do |factory_name|
|
||||||
|
let(:record) { create(factory_name) }
|
||||||
|
let(:field) { record.translated_attribute_names.first }
|
||||||
|
|
||||||
|
describe "Fallbacks" do
|
||||||
|
before do
|
||||||
|
allow(I18n).to receive(:available_locales).and_return(%i[ar de en es fr])
|
||||||
|
|
||||||
|
record.update_attribute(field, "In English")
|
||||||
|
|
||||||
|
{ es: "En español", de: "Deutsch" }.each do |locale, text|
|
||||||
|
Globalize.with_locale(locale) do
|
||||||
|
record.translated_attribute_names.each do |attribute|
|
||||||
|
record.update_attribute(attribute, record.send(attribute))
|
||||||
|
end
|
||||||
|
|
||||||
|
record.update_attribute(field, text)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
allow(I18n).to receive(:available_locales).and_call_original
|
||||||
|
allow(I18n.fallbacks).to receive(:[]).and_call_original
|
||||||
|
Globalize.set_fallbacks_to_all_available_locales
|
||||||
|
end
|
||||||
|
|
||||||
|
context "With a defined fallback" do
|
||||||
|
before do
|
||||||
|
allow(I18n.fallbacks).to receive(:[]).and_return([:fr, :es])
|
||||||
|
Globalize.set_fallbacks_to_all_available_locales
|
||||||
|
end
|
||||||
|
|
||||||
|
it "Falls back to the defined fallback" do
|
||||||
|
Globalize.with_locale(:fr) do
|
||||||
|
expect(record.send(field)).to eq "En español"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "Without a defined fallback" do
|
||||||
|
before do
|
||||||
|
allow(I18n.fallbacks).to receive(:[]).and_return([:fr])
|
||||||
|
Globalize.set_fallbacks_to_all_available_locales
|
||||||
|
end
|
||||||
|
|
||||||
|
it "Falls back to the first available locale" do
|
||||||
|
Globalize.with_locale(:fr) do
|
||||||
|
expect(record.send(field)).to eq "Deutsch"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user