Tuesday, November 20, 2007

Rails Plugin: is_searchable

Announcing is_searchable, provides search functionality for models with ridiculously easy setup.

Here is a model that uses is_searchable:

class Person < ActiveRecord::Base
is_searchable :by_query => 'CONCAT(people.first_name, people.last_name) LIKE :like_query OR people.phone_number LIKE :like_query',
:and_filters => {
'age' => 'people.age = ?',
'over_age' => 'people.age > ?',
'under_age' => 'people.age < ?',
'first_name' => 'people.first_name = ?',
'last_name' => 'people.last_name = ?'
}
end


This code, in the simple form shown above, gives you two functions: Person.search and Person.search_count. Both of these should receive the same arguments (query, options), except that only Person.search will honor limit and offset. Here are some search examples:

Person.search('pa', :filters => {:over_age => 21, :under_age => 40}) #=> finds all middle-aged people with 'pa' in their name.
Person.search('tom') #=> finds all people named Tom or Tommy, etc.
Person.search('', :filters => {:under_age => 21}) #=> finds all people not yet old enough to drink (in the USA).
Person.search('', :limit => 10, :offset => 20) #=> finds the 3rd page of 10 people.


This plugin has been THE search functionality for all my models for a long time now, and it does the job well. It also plays well with my restful_api plugin (hmm, I haven't blogged about that one yet).

Install like any usual rails plugin:
ruby script/plugin install http://svn.behindlogic.com/public/rails/plugins/is_searchable/

And, if you have any questions or problems, please comment!

3 comments:

miskovac said...

How to integrate this plugin with will_paginate ?

Christopher G said...

I'm using acts_as_ferret right now, since it seems easier, how's the performance on this plugin? Also, does it support full-text search and how well?

daniel said...

christopher g: acts_as_ferret actually uses the ferret search engine with its special indexing and all... it provides an easy interface to fast indexed search. This plugin, however, is meant only to provide search methods to your models, with an easy way to set them up, simply using good ol' SQL queries.

In other words, if you don't want to use ferret, use this plugin. In fact, you could use this plugin as well as ferret, to perform different types of searches. This plugin defines the methods #search and #search_count -- so if ferret also uses those, you'd have to rename one or the other.