Meditations on programming, startups, and technology
New Relic

Acts As Suggest plugin

When searching for the word “honnolullu”, Google will promptly suggest “Did you mean: honolulu”. This feature is quite useful because it drastically improves usability. The lack of this exact function makes Wikipedia a pain in the neck as far as searching goes. So much so that I, and I suspect most people, just google for “wikipedia searched_term”.

Hence, I decided to create a small plugin. The acts_as_suggest Rails plugin allows developers to easily add this functionality to any ActiveRecord class, basing the suggestions on the existing values in the table. For example, if you have a table Articles with a column Title, you will be able to retrieve a list of possible corrections for a misspelled article title. The suggestions are not coming from a dictionary, making it very flexible.

Installation



Make sure you have the required Text rubygem, if not please install it: gem install Text

Download acts_as_suggest.zip, extract it and copy the acts_as_suggest folder into the vendor/plugins directory of your application. You’ll also need to restart your web server.

Usage



Assuming you have a model for a table that contains a list of articles, you would start by including acts_as_suggest in your model:

class Article < ActiveRecord::Base
  acts_as_suggest
end

This will provide the model with the suggest method, which is the core of the plugin. At this point you can retrieve suggestions as follows:

Article.suggest(:title, 'honnolullu')
Article.suggest([:title,:author], 'David Copperffelds')

These will return an array of records if the searched string is not misspelled and matches an existing value in the database. If no matches are found, the method will attempt to find similar existing values and return an array of strings (your suggestions). If none of the strings in the given column(s) are close enough, an empty suggestion array is returned.

The return values reflect a fairly common scenario. With a single method call I can retrieve all the records that match a user search, or I can retrieve suggestions to correct the spelling of his/her search if no records are found.

Please check the documentation for further details.

Documentation



You can read the short documentation online here or access the local copy in the /doc folder.

Bugs and Feedback



Here comes a little disclaimer. I wrote this plugin in half an hour, including the basic documentation and a few tests. Therefore, I’ve not yet setup an SVN repository for it; there are just a few test cases (I’m not even publishing them at this time) and it is very likely that there will be bugs, issues or possible improvements required. I’m releasing this .zip file as early as possible, while the code is in its infancy. In this way I can survey user interest and eventually further develop it. So please, send in any feedback and bug reports by email.

UPDATE (02/14/07): I’ve fixed a vulnerability regarding the unsafe handling of tainted data in a finder method (spotted by Alex Wayne). Please download version 0.1.1.

Given the enthusiasm and interest shown by many people, I’m now considering the possibility of starting an actual small project on Rubyforge.

No related posts.


If you enjoyed this post, then make sure you subscribe to my Newsletter and/or Feed.

receive my posts by email

12 Responses to “Acts As Suggest plugin”

  1. ittays says:

    It’s rarely known that if you follow your search with the word ‘info’, Google tries to snippet the Wiki information.

  2. Thanks ittays, that’s a cool tip.

  3. Just wanted to post a comment to say this is totally awesome, despite the fact that no one else seems to have noticed :)

  4. Zach Dennis says:

    This is pretty sweet Antonio… I agree with Hsiu-fan. Great work!

  5. Thanks Ben. Given the amount of interest, I’ll work further on it. ;-)

  6. Alex Wayne says:

    There is a bunch of code in the plugin that look ripe for SQL injection.

    like:

    search_results = self.find(:all, :conditions => “#{fields} = ‘#{word}’”)

    That should be converted to this

    search_results = self.find(:all, :conditions => ["#{fields} = ?", word])

    at the very least, since @word@ will probably be defined by some random user. Also the building of the conditions query when there is more than 1 column needs to updated to fit that method as well.

    Seems like a nifty plugin though! I’ll keep an eye on it. Probably gonna put it to use in our search on “MagneticWorld”:http://magneticworld.com soon.

  7. You’re obviously right Alex, I’ve fixed that.

  8. Arash says:

    Will this be able to suggest based on another index, such as a ferret index?

  9. Hi Arash,

    I plan to move this plugin to rubyforge soon. At that point, I’ll work on expanding it to support further options, like Ferret.

  10. While I like the simplicity of this plugin, and I understand that you wrote in such a short time, you should point out that non-exact matches result in a full table scan. This may cause serious performance issues for large tables. Perhaps, in these cases, one could leverage the acts_as_ferret plugin as a viable alternative.

  11. Hi Bill,

    you’re absolutely right, this plugin is not meant for large tables. I’d like to evolve the plugin and integrate Ferret and/or other text extensions.

Copyright © 2005-2012 Antonio Cangiano. All rights reserved.