在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本地化密钥并进行搜索?
要向用户显示名称,只需针对用户的当前区域设置使用该键即可。