Rails i18n:我可以关闭"翻译丢失"错误吗?

Phi*_*oum 12 ruby-on-rails internationalization

我有一个多租户应用程序,我正在尝试使用i18n gem来允许我们的每个客户根据自己的喜好自定义系统,更改各个页面上的文本,自定义电子邮件等等.不可否认,我并没有使用i18n,因为我打算使用它,因为我实际上并没有翻译不同的"语言",一切都是英文的,但每个客户都有不同的英语,如果这是有道理的.

尽管如此,我还是遇到了我认为i18n gem中一个非常糟糕的设计决策:如果翻译不存在,而不是简单地不进行翻译并打印出通常的翻译,就会产生错误.例如,

<%= distance_of_time_in_words_to_now @press_release.submitted_at %>
Run Code Online (Sandbox Code Playgroud)

出来了

translation missing: en, datetime, distance_in_words, x_days
Run Code Online (Sandbox Code Playgroud)

我的意思是,来吧!我甚至不想要翻译.

我知道发生这种情况的原因是因为我没有加载默认翻译,但我使用ActiveRecord作为后端,我想保持它干净."解决方案"是将所有yaml翻译文件导入我的数据库翻译商店,但这似乎不是一个好主意.如果我将来升级rails怎么办?我将不得不担心保持所有这些翻译同步.

同样,我无法理解为什么这是默认行为.什么时候ANYBODY想要显示那个时髦的错误信息,而不是只使用默认的"3天前"?

无论如何,我的问题是,如果翻译不存在,有没有办法让它自动关闭翻译并使用未翻译的消息?谢谢!

Phi*_*oum 7

这似乎可以解决问题.

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's 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
Run Code Online (Sandbox Code Playgroud)

  • 你究竟要把它放在哪里? (2认同)
  • 可能在`config/initializers /`下的`.rb`文件中. (2认同)

Paw*_*cik 7

如果你有兴趣在处理其他异常使用默认的异常处理程序,从这个修改后的代码菲利普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
Run Code Online (Sandbox Code Playgroud)

此代码将允许您仅捕获需要以不同方式处理的异常.