RAILS + ThinkingSphinx + 2 Models = Search Results for both


Hey everyone,

This is my first Ruby on Rails article, and I’m excited to contribute something to the community (I hope). I decided to write this article due to the fact I had a heck of a time finding this information myself. I’m not claiming to know everything here, just everything I know. I am open for suggestions, and comments. I am simply trying to help someone avoid all the hassle I had as a noob with “ThinkingSphinx/Rails”. Here’s what it’s all about.

(PS, I’m using PostgreSQL for my database, but that shouldn’t matter with this example)

Lets say you need the ability to search at least 2 models in your project and have ThinkingSphinx (TS) return your search results with information from both models. In my case I have an Account model with account information, and then a whole seperate Name model with the name information that is associated with each account.

Example…

account.rb

class Account < ActiveRecord::Base

has_many :names, :dependent => :destroy

# Thinking Sphinx Search Indexes

define_index do

indexes s_account, :sortable => true

indexes s_account_no

indexes names.name, :as => :account_name

end

name.rb

class Name < ActiveRecord::Base

belongs_to :account

# Thinking Sphinx Search Indexes

define_index do

indexes account.s_account, :sortable => true

indexes account.s_account_no

indexes name, :as => :account_name

end


A misconception I had when I started was the fact that I had to setup my search criteria in either my “Accounts” controller or my “Name” controller. This in fact isn’t true. After a bunch of trial and error and misunderstanding I found out that you can setup your search criteria in a seperate controller and model. I  called mine “Results”.   So to keep everything simple I will outline my rails files below, and try to provide some insight as to why I did it that way. The truth of the matter is however…. I did it this way because it worked.  I would love comments from anyone that feels they have a better way.

I already outlined my model files above, so here’s the rest of the info…

ROUTES FILE (I added the following line)

map.resources :results, :collection => {:search => :get}

APPLICATION TEMPLATE

viewslayoutsapplication.html.erb

<% form_tag search_results_path, :method => :get do %>

<div id=”search”>

<%= text_field_tag :search, params[:search], :class => ‘text’ %>

<%= submit_tag ‘Search’, :class => ‘button’ %>

</div>


CONTROLLERS:

accounts_controller

I did nothing to this controller to make it work.

names_controller

again, I did nothing to this controller

results_controller (I created this specifically for searching)

class ResultsController < ApplicationController

def search

@results = ThinkingSphinx::Search.search(params[:search],

:classes => [Account,Name])

respond_to do |format|

format.html #calls the search.html.erb (viewsresultssearch.html.erb)

end

end

end


VIEW FILES

viewsresultssearch.html.erb

<%- @results.each do |result| -%>

<% if result.class == Account %>

<br><%= render :partial => ‘accounts/results’, :locals => {:account => result } %><br>

<% elsif result.class == Name %>

<%= render :partial => ‘names/results’, :locals => {:name => result } %><br><br>

<% end %>

<%- end -%>

<%= will_paginate @results %>

viewsaccounts_results.html.erb

Account: <%= link_to account.s_account_no, edit_account_path(account) %>

viewsnames_results.html.erb

Name: <%=name.name%>

When I was trying to find this information it didn’t make sense to me that I had to render a partial per model. After I set it up, and was able to see the results it seemed to work great. I just got it all setup, and I’m sure I will do some tweaking, but I was eager to post this blog before I got too lazy, or decided I wasn’t qualified yet to post anything about ThinkingSphinx. I’m not representing myself as qualified in this area I simply want to add one more resource for someone else to look at. If you have a better idea, or would like to add a comment, please do so.

  1. #1 by peter at November 23rd, 2009

    Great article. You have exactly what I am looking for.

    Only question is where did you put the viewslayoutsapplication.html.erb, viewsresultssearch.html.erb and viewsaccounts_results.html.erb?

  2. #2 by Lawrence at April 8th, 2010

    thank you so much for this. It would’ve taken me way to long to figure out on my own!

(will not be published)

Anti-Spam Protection by WP-SpamFree

  1. No trackbacks yet.