使用postgre模式为每个租户定制rails i18n

时间:2017-06-23 00:15:42

标签: ruby-on-rails ruby postgresql internationalization rails-i18n

我使用Apartment gem切换到我们应用中每个请求的postgre架构。找到租户后,我会根据数据库字段设置区域设置:

I18n.locale = current_tenant.locale || I18n.default_locale

这非常适合切换语言。现在我收到了客户的请求,要求更改yml文件中的单个密钥。我想给我们的客户一个数据库驱动的方式来覆盖某些键,但我不知道如何设置I18n后端来覆盖单个键。我可以使用active_record gem,但这会全局存储翻译,因此如果我覆盖一个租户,它将覆盖所有。

我认为我需要一种方法来预加载翻译并通过租户子域而不是语言查找它们。我发现的所有方法似乎都是在初始化程序中进行后端加载,而不是按请求进行加载,因此我不确定如何执行此操作。

1 个答案:

答案 0 :(得分:1)

通过“覆盖某些键”,您的意思是键的值吗?

如果是这样,实现这一目标的一种方法是在数据库中,在表格中存储替代 - 让我们称之为custom_overrides

此表格包含以下属性:iduser_idkey_namelocaleexpansion_string以及其他类似时间戳的内容。

<强>修饰:

当客户想要使用key_name,“okn”修改密钥的值时,您将在custom_overrides表中创建新记录。

阅读密钥:

当您阅读密钥时,“okn”而不是

t(:okn)

你会这样做:

CustomOverride.where(
  :key_name => :okn,
  :locale => config.locale,
  :user_id => current_user.id
).first.try(:expansion_string) 
  ||
  t(:okn)

也就是说,始终执行数据库读取以确定key_name是否在current_user定义的locale.yml中,如果不是,则返回到i18n。

您可能最终在生产数据库中拥有已经过时的密钥。您必须将custom_overrides文件与custom_overrides表进行协调(例如,定期运行迁移以删除key_nameen.yml不在<div class="parent"> <div>SIBLING 1</div> <div>SIBLING 2</div> ... <div>SIBLING n</div> </div> 中的条目文件)。