2009-11-01 37 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」,應該在模型層面透明地處理。