2009-11-01 2 views
2

Учитывая есть модель:searchlogic с 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. Ближайшим мне удалось получить workging, был:

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

Который не выглядит хорошо.

ответ

1

Я разработал поисковик. По умолчанию он использует существующие именованные области и столбцы базы данных. Это не может выходить за рамки этого, потому что в конечном итоге он должен создать полученный SQL, используя правильные имена столбцов. Тем не менее, нет никакой возможности для поисковой системы понять, что означает ваш атрибут title: 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» в любом месте своего приложения, что должно заботиться о прозрачности на уровне модели.

Смежные вопросы