Saturday, April 18, 2009

Ruby on Rails Model Auto Completer

When developing web applications nowadays, caring about user interaction is mandatory. Using Ajax technology to allow your system to show information without reloading the whole page is one of the features every web user is getting used to.

One good example on this kind of interaction are those text boxes with auto completion. While the user types some name the system will automatically search for matches to those names in the database, offering sugestions on possible existing values.

However, if such a text edit box is part of a form you also need to populate some hidden fields with the returned ids for the text you found on the database.

Ruby offers a text edit option that will perform auto completion by searching in the database, but it does not populate another field.

The model_auto_completer plugin is perfect for this job! If you have, for example the following models, you can type (and lookup) the name of a contact directly in the Transaction form:

class Contact < ActiveRecord::Base
end

class Transaction < ActiveRecord::Base
belongs_to :contact
end

First thing you gotta do is to install the model_auto_completer plugin using the command:

script/plugin install http://model-ac.rubyforge.org/svn/trunk/vendor/plugins/model_auto_completer

After doing this go ahead and install the default auto_complete plugin from rails:

script/plugin install auto_complete

Then, in your view file, add the call to the method that will render the text_edit for the contact name and the one for the contact_id (which is hidden) will also be automatically added:

<%= belongs_to_auto_completer :transaction, :contact, :name %>

The method in the Transaction controller which gets called by the ajax method must be named accodingly:

def auto_complete_belongs_to_for_transaction_contact_name
@contacts = Contact.find(
:all,
:conditions => ['LOWER(name) LIKE ?', "%#{params[:contact][:name]}%"],
:limit => 10
)
render :inline => '<%= model_auto_completer_result(@contacts, :name) %>'
end

One problem you might run into is to get an error messsage regarding the forgery protection. Something like this:

ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/request_forgery_protection.rb:79:in `verify_authenticity_token'

This message is telling you that the POST command you are sending is not being understood by the gorgery protection mechanism. To overcome this problem, just add the command below to your Transactions Controller:


protect_from_forgery :except => [:auto_complete_belongs_to_for_transaction_contact_name]


Well, this is pretty much everything you need to make this plugin work. Have fun!!

You find this article also on definenull.com.

No comments: