Rails将Scoping路由到数据库中的值

时间:2014-03-18 22:43:29

标签: ruby-on-rails ruby

我正在使用国际化的rails应用程序,使用区域设置作为网址的一部分。我们只在数据库中翻译了某些语言,因此允许用户访问网址中的任何语言环境没有意义。

例如,我们涵盖英语和西班牙语,因此我们当前的routes.rb几乎放置了scope "(:locale)", locale: /en|es/ do...块内的所有内容。我的理解是,这种力量:区域设置,如果存在的话,是" en"或者" es",现在可以正常工作。

我担心的是,不同的客户会希望系统支持其他语言(并且只支持那些语言)。他们将负责创建包含区域设置信息的国际化记录。我想我想自动允许语言环境是数据库中已经定义的任何语言环境,所以我在翻译中添加了一个类方法(国际化记录)

def self.available_locales Translation.uniq.pluck(:locale) end

并将routes.rb更改为scope "(:locale)", locale: Translation.available_locales do...,但这只是让每条路线转到/en/es/the_rest_of_the_url

是否可以告诉rails路由必须使用来自available_locales的结果数组中的语言环境值?

2 个答案:

答案 0 :(得分:1)

我会使用Advanced Constraints

# routes.rb
scope "(:locale)", constraints: LocaleConstraint.new

# i.e. /lib/locale_constraint.rb
class LocaleConstraint
  def initialize
    # get available locales from DB or so
    @locales = Locale.all
  end

  def matches?(request)
    @locales.include?(request.params[:locale])
  end
end

通过这种方式,您还可以编写后端来管理可用的区域设置等。

答案 1 :(得分:0)

你可以把它变成一个正则表达式,所以它匹配你的第一个例子:

Regexp.new([:en, :es].join("|")) #=> /en|es/

或使用您的课程方法(ABMagil'编辑):

Regexp.new(Translation.available_locales.join("|")) #=> /en|es/