开发者

How can I use locales in a model named_scope?

I have a named_scope in my model and want a diffe开发者_如何学编程rent condition, based on the locale. On the development this code works perfect, after switching to production the named_scope doesn't work and I get every time the first condition ("de"). I think it's a caching problem? I'm working with 2.3.5. and env settings out of the box.

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


The value for the conditions option is evaluated during class loading. In the development mode class is loaded for every request. Hence your code works in the development mode.

Create the named scope using a parametrized lambda:

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

You can the lambda as follows:

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


Yes, it's a "problem" with the class caching of rails. In production the class is loaded and then cached, since the condition is evaluated in class context this should be the value of I18n.locale when the class was loaded.

To solve the problem you could simply turn it off by setting

config.cache_classes = false

in your 'config/enviroments/production.yml', but this slows down response time.

A better solution would be to use a lambda and pass in the locale

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
}

Then you can use it like this:

Article.public(I18n.locale)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜