0

我有一个多国 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
4

2 回答 2

1

除了 rmlockerd 所说的,由于fallbacks是一个类变量,我建议您在每次请求后恢复您的回退,以确保您不会意外地将其泄露给同一服务器实例中的其他请求。你可以这样做:

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

(代码未经测试,但应该可以工作或非常接近工作。)

于 2020-07-06T09:00:25.547 回答
1

稍作试验(使用 Rails 6),可以使用 Simple(默认)后端更改回退,但这样做不是线程安全的,如果您基于每个请求执行此操作,可能会导致问题。这有点违反直觉——设置I18n.locale是为每个请求动态设置语言环境的记录方式,因此很自然地假设后备会以相同的方式工作。但是,从i18n源头来看:

唯一不是全局且范围为线程的配置值是 :locale。

即便是这样的表述也不是很清楚。但确实locale被定义为实例变量,而所有其他配置属性都是@@类变量。

I18n 的 Rails 指南说 Simple(默认)后端被设计为只做“可能工作的最简单的事情”,但该框架允许插入超出此范围的自定义后端。因此,实现结果的最佳方法是找到(或创建)一个以线程安全方式支持每个请求回退的后端。


作为参考,如果有人确实需要在初始化程序之外更改语言回退(同样,这是全球性的),请fallbacks.map()执行以下操作:

I18n.fallbacks.map(:ca => :"es-ES")

我最初的回答提到直接摆弄fallback哈希,但使用.map()保留回退到默认语言环境。

于 2020-07-05T20:18:20.227 回答