Search Middleware

Much like Rack and other HTTP libraries, Thinking Sphinx’s searches are constructed and processed by a set of middleware. They take the provided search parameters, generate a query that Sphinx understands, makes the search request, and then translate the resulting values back into ActiveRecord instances.

Each middleware must be a class that is initialized with an app object, has an instance method call which accepts an array of search contexts, and that method should then invoke to continue the chain.

class CustomMiddleware
  def initialize(app)
    @app = app

  def call(contexts)
    # Do custom things here. Perhaps set default search options,
    # or modifications based on the broader application
    # environment, or whatever
    # …

    # … and then, keep the request going: contexts


  attr_reader :app

To add custom middleware into the mix, you can either do this in an initializer so it affects all searches:

# For searches that return ActiveRecord objects
ThinkingSphinx::Middlewares::DEFAULT.insert(0, CustomMiddleware)
# For searches that return raw Sphinx results
ThinkingSphinx::Middlewares::RAW_ONLY.insert(0, CustomMiddleware)
# For searches that return ActiveRecord primary keys
ThinkingSphinx::Middlewares::IDS_ONLY.insert(0, CustomMiddleware)

Or, you can specify a custom middleware stack on a per-search basis:

# A modification of the DEFAULT set:
middlewares = do
  use CustomMiddleware
  use ThinkingSphinx::Middlewares::StaleIdFilter
  ThinkingSphinx::Middlewares.use self,
  use ThinkingSphinx::Middlewares::ActiveRecordTranslator
  use ThinkingSphinx::Middlewares::StaleIdChecker
  use ThinkingSphinx::Middlewares::Glazier
end "foo", :middleware => middlewares

The best place to understand the existing set of middleware is by reading the source code.