ruby-on-rails – 为什么Rails中的区域设置作为全局(使用Thin时)?

我只是意识到,推荐的Rails方式在您的控制器中设置区域设置

before_filter :set_locale

def set_locale
  I18n.locale = params[:locale] || I18n.default_locale
end

设置全局的区域。上面的代码工作,但我不知道default_locale真的默认,如果你必须明确键入?

我期望的是每个请求有一个区域设置(像我们每个请求有会话),并做一些像:

def set_locale
  locale = params[:locale] if params[:locale]
end

默认情况下使用I18n.default_locale。这将理想地匹配路径中的可选区域设置:

# config/routes.rb
scope "(:locale)", :locale => /en|nl/ do
  resources :books
end

现在,如果由于某些原因,我在某些操作中跳过区域设置,它会使用上一个请求中设置的区域设置,这可以来自另一个用户!

并且没有一个潜在的竞争条件,因为一个请求可以改变全局I18n.locale,而另一个请求(已经设置另一个locale)在渲染的中间?

更新:我发现的一些细节,从I18n文件:

Sets the current locale pseudo-globally, i.e. in the Thread.current hash
def locale=(locale)

现在我想了解每个请求是否是单独的线程。

更新2:看到我的答案解释。

所以现在最后的答案。 TL; DR设置区域设置仅当您使用线程Web服务器(如Thin和Puma)时才起全局作用。

正如我所说,I18n.locale =

Sets the current locale pseudo-globally, i.e. in the Thread.current hash

所以它应该是按照请求,它的工作方式在Webrick和Unicorn。

但是,如果您使用Thin或Puma等线程Web服务器,似乎线程寿命更长,并且值将被保留以备将来的请求,直到明确更改为止。我从哪里得知是从新的史蒂夫·克拉夫尼克的宝石request_store

If you need global state, you’ve probably reached for Thread.current.

<…>

So people are using those fancy threaded web servers, like Thin or Puma. But if you use Thread.current, and you use one of those servers, watch out! Values can stick around longer than you’d expect, and this can cause bugs.

翻译自:https://stackoverflow.com/questions/9263036/why-locale-setting-in-rails-acts-as-global-when-using-thin

转载注明原文:ruby-on-rails – 为什么Rails中的区域设置作为全局(使用Thin时)?