Использование Thinking Sphinx и оставаться СУХИМ (Don't Repeat Yourself)

В большом проекте, над которым я работаю, у нас есть много моделей, которые мы хотим индексировать и искать. Я ловлю себя на том, что повторяю вещи снова и снова ... и знаю, что это может быть плохо позже, когда мы будем вносить изменения!

Есть ли хороший способ сохранить код СУХИМ при использовании Thinking Sphinx? В частности, у меня есть следующий блок кода в каждой модели, которую я хочу проиндексировать:

define_index do
  ... # model specific code goes here
  set_property :delta => true
  has :created_at
end

sphinx_scope(:only_active) do
  { :conditions => { :status => 1 } }
end

Я ожидаю, что этот общий код будет расти в размере и функциональности по мере развития проекта ... не говоря уже о том, что могут быть исправления ошибок. Так что, очевидно, я хотел бы это исключить. Я бы хотел сделать что-то вроде:

define_index_with_common_settings do
  ... # model specific code goes here
end

И должны быть автоматически включены общие проиндексированные атрибуты в индекс ... И должны быть определены общие методы и области поиска, связанные с поиском.

Это возможно? Как это делается?


person Jason    schedule 21.12.2010    source источник


Ответы (1)


Вы всегда можете создать миксин для этого:

module CommonSphinxIndexSettings
  extend ActiveSupport::Concern
  module ClassMethods
    def define_index_with_common_settings
      yield self
      set_property :delta => true
      has :created_at
    end

    sphinx_scope(:only_active) do
      { :conditions => { :status => 1 } }
    end
  end
end

Затем добавьте инициализатор, чтобы включить его в AR:

ActiveRecord::Base.send :include, CommonSphinxIndexSettings

При этом все должно оставаться СУХИМ!

Изменить: я внес небольшое изменение (передаю self в вызов yield), это важно из-за типа метапрограммирования, используемого ThinkingSphinx. У этого решения есть свои ограничения, но в большинстве случаев его должно хватить.

person Nicolas Buduroi    schedule 28.05.2012