Rails i18n: Могу ли я отключить ошибки перевода?

У меня есть приложение с несколькими арендаторами, и я экспериментирую с использованием драгоценного камня i18n, чтобы каждый из наших клиентов мог настроить систему по своему вкусу, меняя текст на разных страницах, настраивая электронные письма и т.д. По общему признанию, я не использую i18n, поскольку он был предназначен для использования, поскольку я фактически не переводил разные "языки", все на английском, но каждый клиент имеет РАЗЛИЧНЫЙ английский, если это имеет смысл.

Тем не менее, я столкнулся с тем, что, по моему мнению, является ужасно плохим дизайнерским решением в i18n gem: если когда-либо перевод не существует, а не просто не делает перевод и распечатывает все, что обычно будет, он поднимает ошибка. Например,

<%= distance_of_time_in_words_to_now @press_release.submitted_at %>

появляется как

translation missing: en, datetime, distance_in_words, x_days

Я имею в виду, давай! Я даже не хочу, чтобы это было переведено.

Я понимаю, что причина в том, что это происходит потому, что у меня нет загруженных по умолчанию переводов, но я использую ActiveRecord в качестве бэкэнд, и я хотел сохранить его в чистоте. "Решение" будет заключаться в том, чтобы импортировать все файлы перевода yaml в хранилище для переводов в базе данных, но это не кажется хорошей идеей. Что делать, если я буду обновлять рельсы в будущем? Мне придется беспокоиться о синхронизации всех этих переводов.

Опять же, я не могу понять, почему это поведение по умолчанию. Когда ANYBODY захочет, чтобы появилось это сообщение с фанкой, вместо того, чтобы просто использовать по умолчанию "3 дня назад"?

В любом случае, мой вопрос в том, есть ли способ автоматически отключить перевод и использовать нетранслированное сообщение, если перевод не существует? Спасибо!

Ответ 1

Это похоже на трюк.

require 'i18n' # without this, the gem will be loaded in the server but not in the console, for whatever reason

# store translations in the database translations table
I18n.backend = I18n::Backend::ActiveRecord.new

# for translations that don't exist in the database, fallback to the Simple Backend which loads the default English Rails YAML files
I18nSimpleBackend = I18n::Backend::Simple.new
I18n.exception_handler = lambda do |exception, locale, key, options|
  case exception
  when I18n::MissingTranslationData
    I18nSimpleBackend.translate(:en, key, options || {})
  else
    raise exception
  end
end

Ответ 2

Если вы заинтересованы в обработке других исключений с помощью обработчика исключений по умолчанию, этот модифицированный код из ответа Philip Brocoum должен сделать трюк (версия Rails 3.2.2):

i18n_simple_backend = I18n::Backend::Simple.new
old_handler = I18n.exception_handler
I18n.exception_handler = lambda do |exception, locale, key, options|
  case exception
  when I18n::MissingTranslation
    i18n_simple_backend.translate(:en, key, options || {})
  else
    old_handler.call(exception, locale, key, options)
  end
end

Этот код позволит вам фиксировать только те исключения, которые вам нужно обрабатывать по-разному.