David W Parker - Developer


named_scope and Thinking Sphinx gotcha

published on

I was working with named_scope earlier today and I was have an issue getting it to work properly with a Thinking Sphinx search that I had. This makes sense, as named_scope is not completely supported yet by Thinking Sphinx. Read below for the gotcha and a short-term work around.

I had a named_scope something like this:

named_scope :not_expired, lambda { {:conditions => ["expiration_date >= ?", Time.now.utc]} }

I was calling it in a chain to another method which just called a Thinking Sphinx search:

@posts = Post.not_expired.search_page(params)

My problem came from what came back in my @posts:

Sphinx Result: [85, 44, 26]
Post Load (0.003232)   SELECT * FROM `posts` WHERE (`posts`.`id` IN (85,44,26)) AND (expiration_date >= '2008-11-14 04:15:08') 

All looks fine. But then I would hit a nil object error… huh?

ActionView::TemplateError (You have a nil object when you didn't expect it!
The error occurred while evaluating nil.title) on line #5 of posts.html.haml

Loading up a script/console, I was finally able to see the problem.

>> @posts = Post.not_expired.search_page({:some=>"Param"})
=> some results....
>> @posts.size
=> 3

Somehow combining named_scope with Thinking Sphinx decided to load three posts into my @posts object even though it only found one. So I had something like this:

[< Post id: 1, title: "something">, nil, nil]

And here was my fix (after the query):

@posts = @posts.compact

This throws out the nil results. Hopefully this will help out those out in Google land.

Questions? E-mail me: this domain AT gmail DOT com