在 Rails 中设置每个请求 i18n 回退?
Set per request i18n fallbacks in Rails?
我有一个多国 Rails 应用程序。我需要为每个请求设置 i18n 回退架构。这可能吗?如何实现?
UPD
class Country < ApplicationRecord
# String attribute "languages" (array)
end
class CountriesController < ApplicationController
def show
@country = Country.find params[:id]
I18n.fallbacks = {
@country.languages.first => @country.languages.second
} # This does not work
render 'show'
end
end
稍微试验一下(使用 Rails 6),可以使用简单(默认)后端更改回退,但这样做 不是 线程-安全,如果您根据每个请求执行此操作,则可能会导致问题。这有点违反直觉——设置 I18n.locale
是为每个请求动态设置区域设置的记录方式,因此很自然地假设回退会以相同的方式工作。但是,来自 i18n
来源:
The only configuration value that is not global and scoped to thread
is :locale.
即便如此,措辞也不是很清楚。但确实locale
定义为实例变量,其他所有配置属性都是@@
class变量。
I18n 的 Rails 指南说简单(默认)后端被设计为只做“可能工作的最简单的事情”,但该框架允许插入超出此范围的自定义后端.因此,实现结果的最佳方法是找到(或创建)一个以线程安全方式支持每个请求回退的后端。
作为参考,如果有人确实需要在初始化程序之外更改语言后备(同样,这是全局的),fallbacks.map()
会这样做:
I18n.fallbacks.map(:ca => :"es-ES")
我原来的回答提到直接摆弄 fallback
哈希,但使用 .map()
保留回退到默认语言环境。
除了 rmlockerd 所说的,由于 fallbacks
是一个 class 变量,我建议您在每次请求后恢复回退,以确保您不会不小心将其泄露给其他请求在同一个服务器实例中。你可以这样做:
around_action :restore_i18n_fallbacks
# ...
private
def restore_i18n_fallbacks(&action)
original_fallbacks = I18n.fallbacks
begin
action.call
ensure
I18n.fallbacks = original_fallbacks
end
end
(代码未经测试但应该可以工作或相当接近工作。)
我有一个多国 Rails 应用程序。我需要为每个请求设置 i18n 回退架构。这可能吗?如何实现?
UPD
class Country < ApplicationRecord
# String attribute "languages" (array)
end
class CountriesController < ApplicationController
def show
@country = Country.find params[:id]
I18n.fallbacks = {
@country.languages.first => @country.languages.second
} # This does not work
render 'show'
end
end
稍微试验一下(使用 Rails 6),可以使用简单(默认)后端更改回退,但这样做 不是 线程-安全,如果您根据每个请求执行此操作,则可能会导致问题。这有点违反直觉——设置 I18n.locale
是为每个请求动态设置区域设置的记录方式,因此很自然地假设回退会以相同的方式工作。但是,来自 i18n
来源:
The only configuration value that is not global and scoped to thread is :locale.
即便如此,措辞也不是很清楚。但确实locale
定义为实例变量,其他所有配置属性都是@@
class变量。
I18n 的 Rails 指南说简单(默认)后端被设计为只做“可能工作的最简单的事情”,但该框架允许插入超出此范围的自定义后端.因此,实现结果的最佳方法是找到(或创建)一个以线程安全方式支持每个请求回退的后端。
作为参考,如果有人确实需要在初始化程序之外更改语言后备(同样,这是全局的),fallbacks.map()
会这样做:
I18n.fallbacks.map(:ca => :"es-ES")
我原来的回答提到直接摆弄 fallback
哈希,但使用 .map()
保留回退到默认语言环境。
除了 rmlockerd 所说的,由于 fallbacks
是一个 class 变量,我建议您在每次请求后恢复回退,以确保您不会不小心将其泄露给其他请求在同一个服务器实例中。你可以这样做:
around_action :restore_i18n_fallbacks
# ...
private
def restore_i18n_fallbacks(&action)
original_fallbacks = I18n.fallbacks
begin
action.call
ensure
I18n.fallbacks = original_fallbacks
end
end
(代码未经测试但应该可以工作或相当接近工作。)