Rails i18n中的混合语言环境

时间:2011-02-03 10:28:17

标签: ruby-on-rails internationalization

Rails以某种方式混合我的语言环境,我完全不知道为什么。我翻译的大部分字符串都按预期工作,但对于某些字符串,它会混合使用区域设置。

有趣的是,这只发生在我们的一个系统上。特别是用Apache运行Passenger。

在我的开发系统上使用Webrick,Thin或Passenger Standalone时,一切都会好起来的。

这就是我application.rb中的内容:

config.i18n.default_locale = :de

这是application_controller.rb

before_filter :set_locale

def set_locale
  I18n.locale = @current_client ? @current_client.locale : I18n.default_locale
end

(我在@current_clientnil并执行else部分的网页上遇到问题。

所以,我基本上使用:de语言环境。在表单上显示验证错误时,我会遇到这样的混合翻译:

  

ist zu kurz(nicht weniger als 6 Zeichen)和翻译缺失:en.activerecord.errors.custom.password_format

如您所见,第一次失败验证的错误消息按预期转换,因为第二条错误消息尝试访问英语翻译(不存在)。

我怀疑在before_filter被执行之前,延迟加载已翻译的字符串存在问题。

为什么会发生这种情况的任何线索?

记录:这是Rails 3

修改

我刚刚发现这取决于所使用的环境。使用开发环境时,一切都很好。在使用生产环境(或类似生产环境)时,我会遇到上述行为。

编辑2

我发现了更多:它特别取决于config.cache_classes。设置为true时,我会看到混合翻译。当设置为false时(如在典型的开发环境中),i18n按预期工作。

编辑3

也许这与以下错误有关?

https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/5522

编辑4

这与上面提到的bug有关,问题是由于急切加载的模型类,它们使用I18n字符串,但是在I18n初始化之前发生了急切的类加载,因此找不到翻译。甚至还有另一个错误:

https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/6353

不幸的是,Rails的人没有设法在最近的3.0.4版本中包含修复程序(据我所知)。因此,我试图找出这样的解决方法(在我的应用程序配置中):

 config.before_eager_load do
   I18n.load_path += Dir[Rails.root.join('config', 'locales', 'de.yml').to_s]
   I18n::Railtie.reloader.paths.concat I18n.load_path
   I18n::Railtie.reloader.execute_if_updated
   I18n.reload!
 end

不幸的是,这不起作用。有线索吗?

4 个答案:

答案 0 :(得分:14)

如果您的Gem也使用I18n(我在使用active_admin时遇到此问题),也可能会出现此问题。 Rails将I18n设置为迟到,以便Gem能够使用相同的load_paths。

我所做的是将其添加到production.rb:

config.before_configuration do
      I18n.load_path += Dir[Rails.root.join('config', 'locales', '*.{rb,yml}').to_s]
      I18n.locale = 'pt-PT'
      I18n.reload!
    end

答案 1 :(得分:2)

以下是我的最终解决方法,它似乎有效(根据需要将其放在application.rb或其中一个环境配置文件中):

 # THIS IS A WORKAROUND FOR A I18N BUG IN RAILS!
 # Only required when cache_classes is set to true
 # See https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/6353
 config.before_eager_load do
   I18n.locale = :de
   I18n.load_path += Dir[Rails.root.join('config', 'locales', 'de.yml').to_s]
   I18n.reload!
 end

希望这对其他人有用......

修改

如果这对您不起作用,请尝试使用before_configuration代替before_eager_load(请参阅下面的解决方案)。至少,在Rails 3.0.10中再次作为我的解决方法

答案 2 :(得分:0)

您是否尝试过使用Passenger spawn方法设置?尝试将其设置为保守,这样乘客的行为应该与Thin相同。

答案 3 :(得分:0)

升级到rails 3.0.5应解决此问题和类似的I18n问题。

请参阅:https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/6353