Make Solr / sunspot_rails, Cucumber and VCR bestest buddies

After spending the morning banging my head against another Cucumber problem, I thought the best way to spend an afternoon would be to run into another hilarious jape that Rails 3 threw at me.

Since acts_as_ferret is basically dead for Rails 3, I decided to move a project to Solr. sunspot_rails works brilliantly, until you start using Cucumber. For a few hours that felt like days, I couldn’t understand why in the development environment my Solr searches were working, while in cucumber nothing came back at all.

I spent a while trying to implement this fix for our project, to no avail.

The solution: for a reason I’m yet to fathom to do with the way / frequency that Solr indexes stuff, you must do an explicit Sunspot.commit to ensure any database changes have been stored in the index. I added this to the end of a step definition that set up some data before a search step, and hey presto!

UPDATE: commits normally occur when a controller action finishes, hence why you need to do them manually when creating records outside of controller actions. sunspot_rails inserts an after_filter to do this.

To get to this point, I added some debug lines to net/http in the get and post methods, just to dump out the bodies of the requests and responses. They were initially showing POSTs like:

But after the change, the all-important commit element is added to the end as a separate request:

After I’d discovered this little bastard, VCR worked fine, and now I’ve recorded the responses from Solr I’ll no longer need to faff with a separate search server.

UPDATE 2: adding an AfterStep hook with Sunspot.commit_if_dirty helped DRY up my step definitions.