Rails I18n验证弃用警告

我刚刚更新到rails 4.0.2,我得到了这个警告:

(弃用)I18n。enfort_available_locales将来将默认为true。如果你真的想跳过locale验证,你可以设置I18n。enfort_available_locales = false以避免此消息。

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

63489 次浏览

看起来不是这样的-这是i18n工作方式的前一种行为-当你要求一个未实现/可用的区域时,新行为(true)将引发一个错误。

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

为了完整起见,请注意,你也可以通过在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

I18n.config.enforce_available_locales = true为我工作在Rails 3.2.16(我把它放在config/application.rb)

重要的:确保你的应用没有使用I18n 0.6.8,它有一个阻止正确设置配置的错误


简短的回答

为了关闭警告,请编辑应用程序。并在Rails::Application主体中包含以下行

config.i18n.enforce_available_locales = true

可能取值为:

  • false:如果你
    • 想要跳过区域验证
    • 不要关心locale
  • true:如果你
    • 如果传递了无效的区域设置,希望应用程序引发错误(或)
    • 想默认为新的Rails行为(或)
    • 关心locale验证

注意:

  • 旧的默认行为对应于false,而不是true
  • 如果您正在设置config.i18n.default_locale配置或其他i18n设置,请确保在设置config.i18n.enforce_available_locales设置之后进行设置。
  • 如果你使用包含I18n特性的第三方gems,通过Application config对象设置该变量可能没有效果。在本例中,使用I18n.config.enforce_available_locales将其直接设置为I18n

    说明

例子

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为真时,将引发一个

. I18n::InvalidLocale异常,如果传递的locale不可用

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

如果设置为false,我们将完全跳过强制执行可用区域设置(旧行为)。

这已经通过以下方法实现:

  • 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

config.i18n.enforce_available_locales = false

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

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特性的第三方宝石,设置变量through可能没有效果。事实上,这个问题与上一点所描述的是一样的,只是调试起来稍微困难一些。

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

    .

    这将导致该方法在调用时打印堆栈跟踪。您将能够通过检查堆栈跟踪来确定哪个gem正在调用它(在我的例子中是Authlogic)。

    ["/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 `'",
    "/Users/weppos/Projects/application/app/models/user.rb:1:in `'",
    

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

config.i18n.enforce_available_locales = true

如果locale验证,你可以写false,并且不关心它。