如何在名为named_scope的模型中使用区域设置?

时间:2010-04-20 12:43:58

标签: ruby-on-rails activerecord

我的模型中有一个named_scope,并且根据区域设置需要不同的条件。在开发这个代码工作完美,切换到生产后,named_scope不起作用,我每次都得到第一个条件(“de”)。我认为这是一个缓存问题? 我正在使用2.3.5。和env设置开箱即用。

named_scope :public, 
    :conditions => I18n.locale == "de" || I18n.locale == :de ? ["published=? AND trash=?", true, false] : ["published_#{I18n.locale} =? AND trash=?", true, false]

2 个答案:

答案 0 :(得分:2)

在类加载期间评估conditions选项的值。在开发模式中,为每个请求加载类。因此,您的代码在开发模式下工作。

使用参数化lambda创建命名范围:

named_scope :published, lambda { |*args| { 
                 name = "_de" if (args.first||"").to_s == 'de'
                 :conditions => ["published#{name} =? AND trash=?", true, false]
                }
              }

你可以将lambda如下:

Post.published # no locale passed
Post.published(locale)  # with locale passed

答案 1 :(得分:1)

是的,对于rails的类缓存来说,这是一个“问题”。在生产中,类被加载然后被缓存,因为在类上下文中计算条件,这应该是加载类时I18n.locale的值。

要解决此问题,您只需设置

即可将其关闭
config.cache_classes = false
在你的'config / enviroments / production.yml'中

,但这会减慢响应时间。

更好的解决方案是使用lambda并传入语言环境

named_scope :public, lambda {|l| 
  if l == :de or l == 'de'
    {:conditions => ["published=? AND trash=?", true, false]}
  else
    {:conditions => ["published_#{l} =? AND trash=?", true, false]}
  end
}

然后你可以像这样使用它:

Article.public(I18n.locale)