3

In the large project I'm working on we have many models we want to index and search. I'm finding myself repeating things over and over... and know this could be bad later when we make changes!

Is there a good way to keep code DRY while using Thinking Sphinx? In particular I have the following block of code in every model I want to index:

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

I anticipate this common code to grow in size and functionality as the project evolves... not to mention there may be bug fixes. So obviously I'd like to factor this out. I'd like to be able to do something like:

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

And have the common indexed attributes be automatically included in the index... AND have common search related methods and scopes be defined.

Is this possible? How is it done?

Nicolas Buduroi
  • 3,565
  • 1
  • 28
  • 29
Jason
  • 11,709
  • 9
  • 66
  • 82

1 Answers1

1

You could always create a mixin to do that:

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

Then add an initializer to include it in AR:

ActiveRecord::Base.send :include, CommonSphinxIndexSettings

This should keep everything DRY!

Edit: I've made a small change (passing self to the yield call), this is important because of the type of meta-programming ThinkingSphinx is using. This solution has it's limitation but should be good enough for most cases.

Nicolas Buduroi
  • 3,565
  • 1
  • 28
  • 29