关于ruby:Rails I18n验证弃用警告

Rails I18n validation deprecation warning

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

[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.

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


重要提示:确保您的应用程序没有使用i18n 0.6.8,它有一个错误,会阻止正确设置配置。

简短回答

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

1
config.i18n.enforce_available_locales = true

可能的值为:

  • 假:如果你
    • 希望跳过区域设置验证
    • 不在乎地方
  • 如果你
    • 希望应用程序在传递无效区域设置时引发错误(或)
    • 希望默认为新的Rails行为(或)
    • 关心区域设置验证

注:

  • 旧的违约行为对应于false,而不是true
  • 如果要设置config.i18n.default_locale配置或其他i18n设置,请确保在设置config.i18n.enforce_available_locales设置之后进行设置。
  • 如果使用包含i18n功能的第三方gems,则通过应用程序config对象设置变量可能没有效果。在这种情况下,使用I18n.config.enforce_available_locales直接将其设置为I18n。告诫

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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

长回答

Deprecation警告现在显示在Rails 4(大于等于4.0.2)和Rails 3.2(大于等于3.2.14)中。这个承诺中解释了原因。

Enforce available locales

When I18n.config.enforce_available_locales is true we'll raise an
I18n::InvalidLocale exception if the passed locale is unavailable.

The default is set to nil which will display a deprecation error.

If set to false we'll skip enforcing available locales altogether (old behaviour).

This has been implemented in the following methods :

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

在此更改之前,如果您传递了一个不受支持的区域设置,那么如果区域设置有效(即,如果/config/locales文件夹中有相应的区域设置文件),Rails将自动切换到该区域设置,否则该区域设置将默认为config.i18n.default_locale配置(默认为:en)。

i18n gem的新版本迫使开发人员对语言环境管理有一点意识。

将来,行为会改变,如果区域设置无效,Rails应用程序将引发错误。

在准备此类更改(这可能会破坏一些直到今天仍依赖静默默认值的应用程序)时,警告将强制您在当前转换期间显式声明要执行的验证。

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

1
config.i18n.enforce_available_locales = false

否则,将其设置为true以匹配新的Rails默认值,或者如果您希望在域验证上更加严格,并避免在区域设置无效的情况下切换到默认值。

1
config.i18n.enforce_available_locales = true

告诫

  • 如果您正在设置config.i18n.default_locale配置或使用前面提到的任何方法(default_locale=locale=translate等),请确保在设置config.i18n.enforce_available_locales设置后进行设置。否则,折旧警告将继续弹出。(感谢F_Bio Batista)。

  • 如果使用包含i18n功能的第三方gems,则通过设置变量可能没有效果。事实上,问题与前一点中描述的一样,只是调试起来有点困难。

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

    在这种情况下,您需要跳过Rails堆栈,通过调用

    1
    I18n.config.enforce_available_locales = true

    而不是

    1
    config.i18n.enforce_available_locales = true

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

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

    ></P><P>这将导致方法在调用时打印stacktrace。您可以通过检查stacktrace(在我的例子中,它是authlogic)来确定哪个gem正在调用它。</P></p>
<div class=

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ["/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)>'",

  • 为了完整起见,请注意,您也可以通过在config/application.rb中设置I18n.enforce_available_localestruefalse来消除警告:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    require File.expand_path('../boot', __FILE__)
    .
    .
    .
    module SampleApp
      class Application < Rails::Application
        .
        .
        .
        I18n.enforce_available_locales = true
        .
        .
        .
      end
    end


    I18n.config.enforce_available_locales = true在Rails3.2.16中为我工作(我把它放在config/application.rb中)


    似乎不是这样——这是i18n工作方式的前一种行为——当您请求未实现/可用的区域设置时,新行为(true)将引发错误。

    请参阅添加此警告的提交:https://github.com/svenfuchs/i18n/commit/3b6e56e06fd70f6e4507996b17238505e6608c


    如果您想关心区域设置,请写入appilcation.rb文件。

    1
    config.i18n.enforce_available_locales = true

    如果区域设置验证,则可以编写false,而不关心它。