ruby-on-rails - multi - rails translation interpolation
¿Por qué la configuración regional en Rails actúa como global(cuando se usa Thin)? (2)
Me acabo de dar cuenta de que la forma recomendada de Rails para establecer la configuración regional en tu controlador
before_filter :set_locale
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
end
establece la configuración regional global. El código anterior funciona, pero me pregunto si default_locale
es el predeterminado si tiene que escribirlo explícitamente.
Lo que esperaría es tener una configuración regional por solicitud (como si tuviéramos una sesión por solicitud) y hacer algo como:
def set_locale
locale = params[:locale] if params[:locale]
end
Y teniendo I18n.default_locale
utilizado por defecto de lo contrario. Esto coincidiría idealmente con la configuración regional opcional en la ruta:
# config/routes.rb
scope "(:locale)", :locale => /en|nl/ do
resources :books
end
Por ahora, si por algún motivo omito la configuración regional en alguna acción, utiliza la configuración regional establecida en la solicitud anterior, que podría ser de otro usuario.
¿Y no hay una posible condición de carrera ya que una solicitud puede cambiar el nivel global de I18n.locale
mientras que otra solicitud (habiendo establecido otra configuración regional antes de la I18n.locale
) está en el medio de la representación?
ACTUALIZACIÓN: algunos detalles que encontré por el momento, de la documentación de I18n:
Establece la configuración regional actual pseudo-globalmente, es decir, en la configuración actual de hash Thread.current = (locale)
Ahora quiero entender si cada solicitud es un hilo separado.
ACTUALIZACIÓN 2: ver mi respuesta para una explicación.
El código recomendado de arriba no establece el escenario globalmente, lo establece por solicitud.
before_filter :set_locale
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
end
El código generalmente se coloca en BaseController por lo que antes de procesar cada página, se activa y establece. No hay condiciones de carrera ya que cada página activará este código y la configuración regional I18n se calculará allí. Puede expandir esto para, por ejemplo, buscar la configuración regional de los usuarios, que la configuración regional de la sesión, en vez de solicitar parámetros, que en inglés.
def set_locale
I18n.locale = @user.locale || session[:locale] || params[:locale] || :en
end
En otras palabras, si configura local en una página, digamos en el controlador doméstico de alemán y llegó al panel de control, verá el idioma predeterminado (inglés). Dado que el cambio no es global. Es por eso que el código se coloca en el controlador base. Espero que tenga sentido.
Entonces ahora la respuesta final. TL; DR La configuración regional actúa como global solo cuando se utilizan servidores web con hilos, como Thin y Puma.
Como mencioné, I18n.locale=
Establece la configuración regional actual pseudo-globalmente, es decir, en el hash Thread.current
Entonces se supone que es por solicitud, y funciona de esta manera en Webrick y Unicornio.
Pero si utiliza un servidor web con hilos como Thin o Puma, parece que el hilo dura más tiempo y el valor se conserva para futuras solicitudes, hasta que se modifique explícitamente. Donde aprendí que es de la nueva tienda de gemas de Steve Klabnik:
Si necesita estado global, probablemente haya llegado a Thread.current.
<...>
Entonces la gente está usando esos sofisticados servidores web con hilos, como Thin o Puma. Pero si usas Thread.current y usas uno de esos servidores, ten cuidado. Los valores pueden durar más de lo esperado, y esto puede causar errores.