2009-11-01 92 views
2

鉴于有样板:searchlogic with globalize2?

class MenuItem < ActiveRecord::Base 
    translates :title 
end 

和searchlogic插入时,我期望以下工作:

>> MenuItem.search(:title_like => 'tea') 

可悲的是,它并不:

Searchlogic::Search::UnknownConditionError: The title_like is not a valid condition. You may only use conditions that map to a named scope 

有没有办法让工作?


P.S. 最近我设法得到工作,是:

>> MenuItem.search(:globalize_translations_title_like => 'tea') 

这看起来不太好。

回答

1

我开发了searchlogic。默认情况下,它利用现有的命名范围和数据库列。它不能超越,因为最终它必须使用有效的列名创建结果SQL。也就是说,searchlogic确实无法清楚地理解your:title属性的含义。即使这样做,它也会特定于您的翻译库中定义的逻辑。这是一个红旗,这不应该在图书馆本身,而是一个插件或代码,在您的应用程序中初始化。

为什么不重写method_missing方法并自己做映射? Searchlogic提供了简便的方法,通过做alias_scope范围的别名:

alias_scope :title_like, lambda { |value| globalize_translations_title_like(value) } 

这里有一个快速刺(这是未经测试):

module TranslationsMapping 
    def self.included(klass) 
    klass.class_eval do 
     extend ClassMethods 
    end 
    end 

    module ClassMethods 
    protected 
     def method_missing(name, *args, &block) 
     translation_attributes = ["title"].join("|") 
     conditions = (Searchlogic::NamedScopes::Conditions::PRIMARY_CONDITIONS + 
      Searchlogic::NamedScopes::Conditions::ALIAS_CONDITIONS).join("|")) 

     if name.to_s =~ /^(#{translation_attributes})_(#{conditions})$/ 
      attribute_name = $1 
      condition_name = $2 
      alias_scope "#{attribute_name}_#{condition_name}", lambda { |value| send("globalize_translations_#{attribute_name}_#{condition_name}", value) } 
      send(name, *args, &block) 
     else 
      super 
     end 
     end 
    end 
end 

ActiveRecord::Base.send(:include, TranslationsMapping) 

希望有所帮助。再一次,我没有测试代码,但你应该得到一般的想法。但我同意,翻译的实施应该在幕后,你绝对不应该在你的应用程序的任何位置输入“globalize_translations”,应该在模型层面透明地处理。