我应该如何以DRY和数据库高效的方式存储本地化的值——RubyonRails/i18n



在ActiveRecord模型中维护多语言值的推荐方法是什么。

我正在考虑升级我们的数据库模式和对象模型,以允许许多值的广泛国际化,我正在权衡实现这一点的各种方法。

标准rails-i18n系统在很大程度上对此保持沉默,尽管除了视图中的文本外,它还提供了用于国际化字段和型号名称的强大工具。

R18n-gem允许您用存储本地化字符串的列重载数据库,这些列根据区域设置显示正确的值。这带来了几个问题。

假设我们讨论的是一个模型Sport——数据库表sports。我们需要能够搜索Sport.where(name: 'soccer'),即使在英国他们称之为"足球",所以查询变成了scope :with_name ->(n){ where("name_en_GB = ? OR name_en_AU = ?", n, n) }

如果我们想添加另一个区域设置,我们需要更新模式,并更新该模式上的任何此类查询。一个相当脆弱的解决方案。

我看到的另一个解决方案是维护一个单独的SportLocale模型和相关的sport_locales表,该表包含名称和区域设置。

假设

class Sport < ActiveRecord::Base
  has_many :locales
end
class SportLocale < ActiveRecord::Base
  belongs_to :sport
end

然后为了找到合适的运动,你会做一些类似的事情

class Sport < ActiveRecord::Base
  has_many :locales, class_name: "SportLocale"
  self.with_name(n)
    SportLocale.where(name: n, locale: I18n.locale).first.try(:sport)
  end
end

如果Sport是您唯一的本地化模型,这是可以的,但当您开始添加所有其他模型时,它会变得有点疯狂,每个模型都需要一个相关的*Locale模型。也不是解决方案中的DRY est。

我想要一个允许的解决方案

class Sport < ActiveRecord::Base
  include Localised
  localised_field :name
end

并且神奇地CCD_ 9将找到合适的运动。

有没有这样的系统已经存在,或者我必须自己建立它?其他项目是如何处理这类问题的?

i18n Ruby gem(Rails使用)主要用于静态翻译,即可以被视为代码的一部分的翻译(就像您将视图中的静态硬编码字符串视为代码部分一样)。大多数情况下,这些都存储在静态YAML文件中,因此它们会在部署时发生更改。

我不知道R18n的当前版本。几年前我曾经看过它,它提供了一种做类似事情的替代方法(具有不同的语法和略有不同的功能)。

翻译模型数据是另一项任务。全球化可能是最广泛使用的解决方案,但也有很多其他解决方案。除非你有冒险精神,否则我建议你使用成熟的解决方案,当涉及到更复杂的用例时,翻译数据(以及与ActiveRecord集成)可能会很麻烦。

如果我理解您试图解决的问题,您可能会从Globalize gem中得到一些东西。

它隐藏了您需要的翻译表,但它可以提供一个将"football"[en-au]映射到"football'"[en-uk]的标准,您可以询问您要查找的翻译属性值。

为什么不存储与您的运动相关的I18n本地化密钥并进行搜索?

要向用户显示名称,只需针对用户的当前区域设置使用该键即可。

最新更新