存储在DataBase中的Rails多语言(由最终用户翻译)

时间:2014-11-27 22:33:13

标签: ruby-on-rails ruby-on-rails-3 multilingual

我们对于需要实施的功能存在困境。我们希望在我们的应用中支持n种语言(0 < n < +infinity)。

我们决定采用以下解决方案:

module TranslatedAttributes

  def use_translated_attributes
    has_many :translated_attributes, as: :owner
    accepts_nested_attributes_for :translated_attributes

    define_method :translate_attribute do |attribute, locale = I18n.locale|
      TranslatedAttribute.where(attribute_name: attribute.to_s, owner_type: self.class.model_name, owner_id: self.id, locale: locale.to_s).first.try(:translation)
    end
  end
end

例如,用户应该能够为产品模型的实例定义X翻译。此外,根据用户在其个人资料中设置的区域设置,他将看到该属性的翻译版本。

示例:

Product
  id: 12
TranslatedAttribute
  attribute_name: 'name'
  owner_id: 12
  owner_type: 'Product'
  locale: 'en'
  translation: 'Magnificent shiny shoes'
TranslatedAttribute
  attribute_name: 'name'
  owner_id: 12
  owner_type: 'Product'
  locale: 'fr'
  translation: 'Magnifiques chaussures brillantes'

在视图中,它将被称为:

product.translate_attribute(:name)
# or we will eventually define_method for each attribute to be translated
# so we could use the following
# product.name

这项工作已经过测试。

问题当我们尝试加载大量记录时,每个记录都需要查询数据库以了解要显示的正确翻译。

我的问题是:您如何处理CACHE?

我的另一个问题是:你看到的另一个问题是我到目前为止看不到的吗?另外,我考虑accepts_nested_attributes_for :translated_attributes使用fields_for构建翻译表单。你觉得像这样处理它是个坏主意吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

您可以使用globalize3 gem之类的内容来实现此功能。

答案 1 :(得分:1)

第一个优化可能是在第一次调用translate_attribute时获取Product实例的所需语言环境[1]中的所有翻译,并将它们缓存在实例变量中。

这样,产品实例的翻译请求数量将减少到只有一个。

快速举例:

define_method :translate_attribute do |attribute, locale = I18n.locale|
  locale = locale.to_s
  @attributes_translations_cache ||= {}
  @attributes_translations_cache[locale] ||= Hash[
    self.translated_attributes
        .where(locale: locale)
        .map do |translated_attribute|
          [translated_attribute.name, translated_attribute.translation]
        end
  ]
  @attributes_translations_cache[locale][attribute]
end

我认为也应该以{{1​​}}或至少join以某种方式对产品进行翻译,但我还没有考虑过这个想法。我将尝试更新此答案。

[1]这假设您只在给定页面中使用单个区域设置,但您也可以同时获取所有区域设置,或者区域设置和属性的任意组合。