searchlogic с globalize2? - PullRequest
       11

searchlogic с globalize2?

2 голосов
/ 01 ноября 2009

Имеется модель:

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 Ответ

1 голос
/ 01 марта 2011

Я разработал 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» где-либо в вашем приложении, что должно быть прозрачным для уровня модели.

...