A few of the JRuby on Rails apps I run use
acts_as_solr. Turns out that the prefered search solutions in Rails today are
Thinking Sphinx and
Xapian, neither of which I've ever tried before... maybe on my next project. Anyway, acts_as_solr is pretty useable, however, I've always been stumped with how to perform queries across ActiveRecord models. Turns out that acts_as_solr has a method called "
multi_solr_search" which performs queries across models. However, it's not very well documented and there's not a whole lot of information in the intertubes. So, here's how I got my unified site search to work:
[code lang="ruby"]
# search_controller.rb: default execution searches multiple models. If a scope param is provided
# it will search only that model. multi_solr_search can return two two different formats, the object
# name and id, or the actual object. If you're query returns a lot of results, you don't want to load
# up every single object. The code below loads the object name and id then just loads the object
# for the current paginated group. This is using will_paginate.
def all
if params[:scope] and ["UserProfile", "Idea", "Question", "Group"].include?(params[:scope].classify)
scope = params[:scope].classify
models = [scope]
else
scope = "UserProfile"
models = [Idea, Question, Group]
end
# execute solr multi model search based on the scope selected above
solr_results = scope.constantize.multi_solr_search(params[:q],
:models => models,
:results_format => :ids,
:limit => 1000).docs.compact
@total = solr_results.size
solr_results = solr_results.map {|m| r = m.fetch("id").split(":")}
per_page = 10
page = params[:page] || 1
# determine array indices that are to be included in the current paginated group
first_idx = (page.to_i > 1) ? ((page.to_i - 1) * per_page) : 0
last_idx = (first_idx + per_page.to_i - 1)
last_idx = last_idx page, :per_page => per_page)
end
[/code]
I'd love to see if someone could clean this up more. Any takers?