Topic: HOWTO: Search with ferret/acts_as_ferret/will_paginate

Hi

This is an example of how i managed to get some basic search functionality working on my current development project. I am writing this from the perspective of a Windows user...I am using Vista Ultimate with InstantRails (Rails version 1.2.6).

First you need to install ferret.

Go to:

http://rubyforge.org/frs/?group_id=1028

Download the latest win32 gem to C:\InstantRails:

ferret-0.11.5-mswin32.gem

Then open your Ruby Console Window to C:\InstantRails and install the gem:

gem install ferret

Now install the plugin via Subversion:

svn://projects.jkramer.net/acts_as_ferret/tags/stable/acts_as_ferret

Make sure you have the following line at the top of your config/environment.rb file:

require 'ferret'

I like to create a separate controller to handle searches:
generate controller Searches

Now add a search form to your website:
<% form_tag({:controller => 'searches', :action => 'index'}, :method => 'get') do %>
<%= text_field_tag "q", params[:q] %>
<%= submit_tag "Search!" %>
<% end %>

Or, if you want things done RESTfully, add a 'searches' resource to your routes.rb file:
map.resources :searches

And try this below...note that you should specify that this is a GET request, otherwise Rails will presume that it is a POST request.
<% form_tag(searches_path, :method => 'get') do %>
<%= text_field_tag "q", params[:q] %>
<%= submit_tag "Search!" %>
<% end %>

You then need to specify which models you want users to be able to search. You can optionally also specify which fields to look in...eg:
class Story
acts_as_ferret :fields => [:title, :description]
end

Now let's create the controller action that will allow the magic to happen!
class SearchesController
def index
if params[:q]
query = params[:q]
@stories = Story.find_by_contents(query, :limit => :all)
end
end
end

Now the view, searches/index.rhtml:
<% @stories.each do |s| %>
<%= link_to s.title, story_path(s.id) %>
<% end %>

That should be all to get you going.

When you do your first search, a directory called 'index' will be automatically created. This will be automatically updated. If you find that your searches display no results, or results only sometimes (this happened to me when i first tried getting acts_as_ferret to work, it might be an issue with ferret, i'm not too sure) - try this...

1. Stop the server.
2. Delete the 'index 'directory.
3. Restart server.
4. Run search again!

Adding pagination to your search results is made easy with the will_paginate plugin:

svn://errtheblog.com/svn/plugins/will_paginate

Modify the @stories instance variable in the Searches Controller as follows:

@stories = Story.find_with_ferret query, :page => params[:page], :per_page => 5

Now add this to the bottom of your view, searches/index.rhtml:
<%= will_paginate @stories %>

That's paginated search in rails!

For more info on ferret, acts_as_ferret, and will_paginate, follow the links below:

http://ferret.davebalmain.com/trac/
http://projects.jkraemer.net/acts_as_ferret/
http://errtheblog.com/posts/56-im-paginating-again

Happy searching!

Visit my blog smile

http://therailscoder.blogspot.com/

Last edited by pjay79 (2008-01-26 08:28:59)

Re: HOWTO: Search with ferret/acts_as_ferret/will_paginate

Edit: Just upgraded to Rails 2.0.2, and the search still works smile

PJ.

Re: HOWTO: Search with ferret/acts_as_ferret/will_paginate

Very cool tutorial.  Pretty clear too.  Forgive the criticism, but if you can just clarify for the reader the following line:

You then need to specify which models you want users to be able to search. You can optionally also specify which fields to look in...eg:

Where i was slightly confused, was in the fact that you need to add the code which follows into the Model in which you want to search.  For instance, you may want to let people know :" I am going to insert the following code in my Story Model. The acts_as_ferret plugin will search the title and description fields in my database." or something to that effect.

Right now i'm thinking out loud, but if i wanted to search, say a story model and a blog model, i can just keep continuing to add these acts_as_ferret statements to each model, and all the results will appear, based on the models with that code added.  Of course, for each model, they all have different field names, so one would have to make it model specific, but hey, it's still a fantastic plugin and good tutorial.

it's almost perfect dude.  thanks.  helped a bunch.

Re: HOWTO: Search with ferret/acts_as_ferret/will_paginate

Thanks nerb,

The way i wrote that sentence was that not clear, but what you have paraphrased is exactly what i meant, i will make that change in my blog entry.

smile

PJ.

http://therailscoder.blogspot.com/

Re: HOWTO: Search with ferret/acts_as_ferret/will_paginate

Wow! Even though I'm a Rails programming newbie, I had no problem understanding this, and I think it's exactly what I was looking for. I'll try it out.

Re: HOWTO: Search with ferret/acts_as_ferret/will_paginate

One question - Can you submit multiple search words in one search, and if so will the search be based on AND or OR operations?