【问题标题】:Rails store categories in different languagesRails 以不同语言存储类别
【发布时间】:2011-06-23 08:26:03
【问题描述】:

我正在构建一个多语言应用程序,它有两个基本模型 CategoryProduct,其中一个 Category 有许多 Products..

所以我希望能够用一种以上的语言显示相同的类别,例如,考虑一个名为 Cars 的类别,对于使用法语版本的用户,它应该显示为 Vehicules应用。

我怎么能这样做?我应该将它们存储在不同的模型中吗?还是应该在 Category 模型中添加 lang 列?

我想做的是在 Category 模型中添加一个 lang 列,并添加一个 default_scope 调用来限定它以仅搜索所需的语言,我有两个不过问题:

  1. 如何从模型内部获取使用的语言,即 I18n 调用?我应该调用哪个方法?
  2. 使用此技术会出现问题,引用法语类别的产品不会显示在英语类别下的搜索中,我该如何解决此问题?

谢谢

【问题讨论】:

  • 你想要I18n.t :carts, :locale => :fr这样的东西吗?
  • 类似的东西,但由于类别是动态的,我不能只翻译所有可能性

标签: ruby-on-rails internationalization model


【解决方案1】:

您必须问自己的关键问题是,Cars 类别是否应该与 Vehicules 类别是相同的对象(意味着相同的对象和相同的 URL)是否重要。

如果它们应该属于同一类别,那么唯一的问题是如何将名称翻译成不同的语言。如果您要支持的语言数量相对较少,您可以使用不同的列(name_enname_fr 等)将它们全部存储在模型中。

或者您可以单独存储翻译后的名称,例如使用I18n 模块。

或者,如果 Cars 和 Vehicules 是单独的类别,那么您可以按照您的建议为模型添加 lang 属性。

【讨论】:

  • +1 表示关于使用列作为翻译名称的部分。这是最简单、最可靠的解决方案 - 如果用户正在创建类别,那么只有用户可能能够可靠地翻译它们。
【解决方案2】:

Frankie Roberto 给了你一个很好的答案。我将添加一些额外的信息。

首先是简单的部分:在模型中获取当前语言环境

如果您将控制器中的语言设置为I18n.locale = something,那么您可以以相同的方式在模型中读取它。毕竟I18n 是一个全局常量。

现在关于搜索

我通常更喜欢只有一个类别的设计,但该类别的名称被翻译成多种语言。一辆车属于“汽车”类别而另一辆车属于“车辆”的设计是有缺陷的恕我直言。在后一种情况下,将其设为单一站点是没有意义的 - 您可以创建一个单一语言的应用程序,并将其安装在多个实例中,每个实例都被翻译成一种语言。

如果您有一个简短的、静态的受支持语言列表,您可以为每种语言添加一列:name_enname_frname_pl

如果在设计应用程序时您的语言列表很大或未知,则将“名称”(作为示例)存储为序列化哈希会更容易。因此,您可以得到预期的翻译为name["fr"]name["de"] 等等。

我已经了解到(困难的方法 :-)) 用户通常懒得提供所有的翻译(或者他们只是不知道所有的语言),因此您应该做好准备,您的某些模型将包含您尝试显示或搜索的语言的数据。

对于每个“翻译”属性,您可能需要准备一种方法,该方法将为您提供最合适的翻译,以防所需的翻译丢失。

此方法的工作方式可能类似于:

def translated_name
  ([I18n.locale] + other_languages).each do |l|
    return name[l] unless name[l].blank?
  end
  return "" # or some default value - possibly from I18n.t("some.static.default")
end

当然,您不需要使用 I18n.locale,您应该以(理想情况下)匹配用户语言偏好的方式定义 other_languages,可能通过分析“Accept-Language”标头。

我有时会使用方法名称name_for(lang)name_in(lang),如果我必须支持更多的数据语言而不是接口(我将翻译并放入 I18n 配置文件)。

啊,是的 - 搜索。 :)

如果您已将“名称”定义为单独的属性,则只需搜索相应的列即可。

如果您将“名称”作为单个序列化哈希,您可以将列作为简单文本搜索(但是我不确定 YAML 是否不会破坏非 ASCII 字符)或者创建另一个包含可搜索数据的列,然后(在模型级别,而不是在 SQL 级别) 将模型分成组:“搜索字符串已在您的语言中找到”,“The已找到其他语言的搜索字符串”。我相信多语言服务的用户会对以这种方式呈现的搜索结果感到满意。

【讨论】:

  • 感谢您的详细回答,我想我会将您的一些想法与 puret gem 背后的想法结合起来,例如搜索连接模型比 YAML 列更容易,但使用更可定制我自己替换缺失翻译的逻辑(或者只是修补 puret 以便更可定制:))...谢谢
【解决方案3】:

我正在使用这个 gem 来解决这种问题:https://github.com/jo/puret

【讨论】:

  • 也许您可以简要概述一下该 gem 如何帮助解决问题?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-23
  • 1970-01-01
  • 2015-12-14
  • 1970-01-01
  • 2011-12-18
  • 2022-12-10
相关资源
最近更新 更多