Rails I18n 验证已弃用警告

390

我刚刚更新到Rails 4.0.2,出现以下警告:

[已弃用]I18n.enforce_available_locales在将来会默认为真。如果您真的想跳过对语言环境进行验证,您可以设置I18n.enforce_available_locales=false以避免此消息。

将其设置为false是否存在安全问题?


显然,这也会发生在Rails 4.0.1应用程序中。 - lucke84
2
我在Rails 3.2.16上也有同样的问题。根据下面Simone Carletti的回答,这个问题在Rails 4(>= 4.0.2)和Rails 3.2(>= 3.2.14)中已经解决。 - Mark Berry
5个回答

617

重要提示:请确保您的应用程序未使用I18n 0.6.8,它存在一个错误,会导致配置无法正确设置


简短回答

为了消除警告,请编辑application.rb文件并在Rails::Application主体内包含以下行:

config.i18n.enforce_available_locales = true
可能的值包括:
  • false:如果您
    • 想要跳过区域设置验证
    • 不关心区域设置
  • true:如果您
    • 希望应用程序在传递无效的区域设置时引发错误(或者)
    • 希望默认为新的Rails行为(或者)
    • 关心区域设置验证

注意:

  • 旧的默认行为对应于false,而不是true
  • 如果您正在设置config.i18n.default_locale配置或其他i18n设置,请确保在设置config.i18n.enforce_available_locales设置之后进行。
  • 如果您使用的是包含I18n功能的第三方gem,请通过Application config对象设置变量可能无效。在这种情况下,可以直接将其设置为I18n.config.enforce_available_locales

警告

require File.expand_path('../boot', __FILE__)

# ...

module YouApplication
  class Application < Rails::Application

    # ...

    config.i18n.enforce_available_locales = true
    # or if one of your gem compete for pre-loading, use
    I18n.config.enforce_available_locales = true

    # ...

  end
end

长答案

现在,在Rails 4(>= 4.0.2)和Rails 3.2(>= 3.2.14)中都会显示弃用警告。原因在于此提交中有所解释。

强制可用语言环境

I18n.config.enforce_available_locales 设置为 true 时,如果传递的语言环境不可用,我们将引发 I18n::InvalidLocale 异常。

默认设置为 nil,这将显示一个弃用错误。

如果设置为 false,我们将完全跳过强制可用语言环境的检查(旧行为)。

这已经在以下方法中实现:

  • I18n.config.default_locale=
  • I18n.config.locale=
  • I18n.translate
  • I18n.localize
  • I18n.transliterate

在此更改之前,如果传递了不支持的语言环境,则 Rails 会在语言环境有效时默默地切换到该语言环境(即如果在 /config/locales 文件夹中存在相应的语言环境文件),否则语言环境将默认为 config.i18n.default_locale 配置(默认为 :en)。

I18n gem 的新版本强制开发人员更加注意语言环境管理。

将来,如果语言环境无效,Rails 应用程序将会引发错误。

为了准备这种变化(可能会破坏直到今天仍在依赖静默默认值的多个应用程序),警告正在强制您在当前过渡期间明确声明要执行的验证。

要恢复先前的行为,只需将以下配置设置为 false

config.i18n.enforce_available_locales = false
否则,将其设置为true以匹配新的Rails默认值,或者如果您想在域验证方面更加严格并避免在无效区域设置时切换到默认值,请将其设置为true。
config.i18n.enforce_available_locales = true

注意事项

  1. 如果您设置了config.i18n.default_locale配置或使用先前提到的任何方法(default_locale=, locale=, translate等),请确保在设置config.i18n.enforce_available_locales之后进行。否则,弃用警告将继续出现。(感谢Fábio Batista)。

  2. 如果您使用包含I18n功能的第三方gem,通过设置变量可能不会生效。实际上,这个问题与前面描述的一样,只是稍微难以调试一些。

    这个问题是一个优先级问题。当您在Rails应用程序中设置配置时,该值不会立即分配给I18n gem。Rails会将每个配置存储在内部对象中,加载依赖项(Railties和第三方gem),然后将配置传递给目标类。如果您使用了一个调用任何I18n方法的gem(或Rails插件),而在配置被分配给I18n之前,则会收到警告。

    在这种情况下,您需要跳过Rails堆栈,并通过调用以下方法将配置立即设置到I18n gem中:

I18n.config.enforce_available_locales = true

取代

config.i18n.enforce_available_locales = true

问题容易被证明。 尝试生成一个新的空的Rails应用程序,您将看到在application.rb中设置config.i18n可以正常工作。

如果在您的应用程序中不起作用,则有一种简单的方法来调试罪犯。 找到系统中的i18n gem,在i18n.rb文件中打开并编辑enforce_available_locales!方法,以包含语句puts caller.inspect

这将导致该方法在每次调用时打印堆栈跟踪。 您将能够通过检查堆栈跟踪(在我的情况下是Authlogic)确定是哪个gem在调用它。

["/Users/weppos/.rvm/gems/ruby-2.0.0-p247@application/gems/i18n-0.6.9/lib/i18n.rb:150:in `translate'",
 "/Users/weppos/.rvm/gems/ruby-2.0.0-p247@application/gems/authlogic-3.1.0/lib/authlogic/i18n/translator.rb:8:in `translate'",
 "/Users/weppos/.rvm/gems/ruby-2.0.0-p247@application/gems/authlogic-3.1.0/lib/authlogic/i18n.rb:79:in `translate'",
 "/Users/weppos/.rvm/gems/ruby-2.0.0-p247@application/gems/authlogic-3.1.0/lib/authlogic/acts_as_authentic/email.rb:68:in `validates_format_of_email_field_options'",
 "/Users/weppos/.rvm/gems/ruby-2.0.0-p247@application/gems/authlogic-3.1.0/lib/authlogic/acts_as_authentic/email.rb:102:in `block in included'",
 "/Users/weppos/.rvm/gems/ruby-2.0.0-p247@application/gems/authlogic-3.1.0/lib/authlogic/acts_as_authentic/email.rb:99:in `class_eval'",
 "/Users/weppos/.rvm/gems/ruby-2.0.0-p247@application/gems/authlogic-3.1.0/lib/authlogic/acts_as_authentic/email.rb:99:in `included'",
 "/Users/weppos/.rvm/gems/ruby-2.0.0-p247@application/gems/authlogic-3.1.0/lib/authlogic/acts_as_authentic/base.rb:37:in `include'",
 "/Users/weppos/.rvm/gems/ruby-2.0.0-p247@application/gems/authlogic-3.1.0/lib/authlogic/acts_as_authentic/base.rb:37:in `block in acts_as_authentic'",
 "/Users/weppos/.rvm/gems/ruby-2.0.0-p247@application/gems/authlogic-3.1.0/lib/authlogic/acts_as_authentic/base.rb:37:in `each'",
 "/Users/weppos/.rvm/gems/ruby-2.0.0-p247@application/gems/authlogic-3.1.0/lib/authlogic/acts_as_authentic/base.rb:37:in `acts_as_authentic'",
 "/Users/weppos/Projects/application/app/models/user.rb:8:in `<class:User>'",
 "/Users/weppos/Projects/application/app/models/user.rb:1:in `<top (required)>'",

20
如果您正在设置 config.i18n.default_locale 配置,请确保在设置新的 config.i18n.enforce_available_locales 设置之后进行。否则,弃用警告将继续弹出。 - Fábio Batista
3
只有当我设置I18n.enforce_available_locales = true时才起作用,config.i18n.enforce_available_locales = true不起作用。 - Pioz
1
@Pioz 这可能是由于您的应用程序依赖于的 gem 导致的。我更新了帖子来解释原因。 - Simone Carletti
我也曾经有同样的想法,花了数小时寻找答案,发现与语言-国家格式相对应的区域设置存在一个错误:https://dev59.com/62Ij5IYBdhLWcg3wOCyS - givanse
1
需要注意的是,例如必须设置 I18n.config.available_locales = [:your_locale, :en],否则您将无法启动Rails服务器。 - Tamer Shlash
显示剩余5条评论

45

仅为完整性起见,注意您还可以通过在config/application.rb中将I18n.enforce_available_locales设置为true(或false)来消除警告:

require File.expand_path('../boot', __FILE__)
.
.
.
module SampleApp
  class Application < Rails::Application
    .
    .
    .
    I18n.enforce_available_locales = true
    .
    .
    .
  end
end

9
config.i18n.enforce_available_locales设置为true,是否更加简洁? - Mischa
2
我使用的是3.2.16版本,我将I18n.enforce_available_locales设置为false,但我仍然收到该消息... - CLod
3
@Mischa,那对我没用,但上面的答案有效。 - Mike Atlas
1
很遗憾,没有,必须通过 I18n.config 才能产生影响。 - Ev Dolzhenko
3
在Rails 4.0.2中,将config.i18n.enforce_available_locales = true放在其他config.i18n行的前面,可以消除我遇到的废弃警告。 - balexand
Rails 3.2.16,只有 I18n.enforce_available_locales = 版本有效。 - ExiRe

15

I18n.config.enforce_available_locales = true 对我在Rails 3.2.16中起了作用(我将其放在了config/application.rb文件中)。


10

0
如果您想关注本地化,请写入application.rb文件。
config.i18n.enforce_available_locales = true

如果您不关心区域设置验证,可以写false。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接