我正在构建一个多重应用程序,它有两个基本模型类别和产品,其中类别有许多产品< /强> ..
所以我希望能够使用多种语言显示相同的类别,例如,考虑一个名为Cars的类别,对于使用法语版本的用户,它应该显示为 Vehicules 应用
我怎么能这样做?我应该把它们存放在不同的型号吗?或者我应该在类别模型中添加 lang 列?
我想要做的是在Category模型中添加 lang 列并添加 default_scope 调用以将其范围仅搜索所需的语言,我有两个但问题是:
谢谢
答案 0 :(得分:2)
您必须问自己的一个关键问题是,汽车类别是否应与汽车类别相同的对象(暗示相同的对象和相同的URL)是否重要。
如果它们属于同一类别,那么唯一的问题是如何将名称翻译成不同的语言。如果您支持的语言数量相对较少,则可以使用不同的列(name_en
,name_fr
等)将它们全部存储在模型中。
或者您可以单独存储翻译的名称,例如使用I18n
模块。
或者,如果Cars和Vehicules是单独的类别,那么您可以按照建议向模型添加lang
属性。
答案 1 :(得分:1)
Frankie Roberto 给了你一个很好的答案。我将添加一些额外的信息。
首先是简单部分:在模型中获取当前区域设置。
如果您将控制器中的语言设置为I18n.locale = something
,那么您可以以相同的方式在模型中阅读它。毕竟,I18n
是一个全局常量。
现在关于搜索:
我通常更喜欢您拥有一个类别的设计,但该类别的名称已翻译为多种语言。一辆车属于“汽车”类别而另一辆属于“汽车”类别的设计是有缺陷的恕我直言。在后一种情况下,没有任何意义可以使它成为单个站点 - 您可以创建一个单语言应用程序,并将其安装在多个实例中,其中每个实例都被翻译成单一语言。
如果您有一个简短的静态受支持语言列表,则可以为每种语言添加一列:name_en
,name_fr
,name_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”标题。 / p>
我有时会使用方法名称name_for(lang)
或name_in(lang)
,如果我必须支持更多的数据语言而不是接口(我将翻译并放入I18n配置文件中)。
啊,是的 - 搜索。 :)
如果您已将“名称”定义为单独的属性,则可以只搜索相应的列。
如果您将“名称”作为单个序列化哈希,则可以将该列作为简单文本进行搜索(但我不确定YAML是否不会破坏非ASCII字符)或者使用可搜索的数据创建另一个列,然后(在模型级别,而不是在SQL级别)将模型划分为组:“已在您的语言中找到搜索字符串”,“搜索字符串已在其他语言中找到“。我相信多语服务的用户会对以这种方式呈现的搜索结果感到满意。
答案 2 :(得分:0)
我正在使用这个宝石来解决这类问题:https://github.com/jo/puret