Recently, while working on a small application on Rails, I learned firsthand how easy and powerful RJS can be. I was amazed at how simple it is to save attributes to the data base using Ajax and then notify the user about successful operations or errors. Here is a small example that should show you how simple this is.

The Model

For the purpose of this short example, I’ll consider a table with only one field other than ‘id’. Here is the migration for it:

class CreatePersons < ActiveRecord::Migration
  def self.up
    create_table :persons do |t|
     t.column :name, :string, :null=>false
    end
 end
 
 def self.down
  drop_table :persons
 end
end

The View

In the view on the ‘index’ page the table is rendered as:

<h1>List of Persons</h1>
<div id="error"  style="display:none;" >&nbsp;</div>
<div id="notice”  style="display:none;" >&amp;nbsp;</div>
<table id="person_list">
  <tr>
    <td width="300px"><strong>Name</strong></td>
  </tr>
  <%= render :partial => ‘person’, :collection=>@persons %>
</table>
<%=link_to_function 'New Person’, "Element.show('new_person')"%>
<div id="new_person" style="display:none;">
<% form_remote_tag(:url => {:action => 'create'},
:html => {:id => 'person_form'}) do %>
<strong>Name:</strong><br/><%= text_field "person", "name" %>
<%= submit_tag "Save"%>
<%end%>
</div>

The partial contains the following:

<tr>
  <td><%= person.name%></td>
</tr>

Basically the controller returns a list of all persons and this is looped and displayed through the partial. There is also a hidden form that submits a new name to be added to the database through Ajax. The form is made visible on clicking the “New Person” link and submits to the “create” method in the controller.

The Controller

The “create” method does the following:

1
2
3
4
5
6
7
8
9
10
11
def create
 @person = Person.new(params[:person])
 if @person.save
  flash[:notice] = 'A Person was added successfully to the database'
 else
  render :update do |page|
   page[:error].show
   page.insert_html :bottom, :error, error_messages_for(:person)
  end
 end
end

Here,  first the person object is created from the request parameters. Then the values are added to the database. If they are successfully added, then a message is added to the flash. If there are any errors, then we extract any errors and display them on the page. This is done via the really cool feature of Rails called RJS. RJS lets us generate JavaScript on the fly by only writing ruby code. In this example, line 7 selects the error div and makes it visible. Line 8 inserts the error messages into the error div. The resulting JavaScript is executed on the page. The end result – the errors are displayed in the error div in case of errors.

RJS Magic

Sweet? Well this only the tip of the iceberg. I’ll take things a wee bit further and show you what happens when we add a little RJS template called “create.rjs”. The code for this template is shown below:

# Hide Form &amp; Error
page[:person_name].text=""
page[:new_person].hide
page[:error].hide
 
# Show Notice and add disappearing effect
page[:notice].show
page.insert_html :bottom, :notice, flash[:notice]
page.delay(5) {page[:notice].visual_effect :fade}
 
# Add row to table
page.insert_html :bottom, :person_list, :partial=&gt;'person', :object=&gt;@person

Well here is how it works. The first three lines basically set the text field on the form to blank, hide the form and any visible errors (You can even overwrite the error div contents so that they contain no errors on successful saves). Next we show the notice div and add the notice message to the div. Now here is the really cool part, the next line adds a Fade effect via the script.aculo.us animation framework and sets the delay to 5 seconds for this effect. This shows the notice message for 5 seconds after which the message fades out. What’s really cool about this, is that it’s just one line of Ruby code and no messy JavaScript in sight (Of course the last line updates the table with the newly added person entry).

I think this example goes a long way in showing how productive Rails is. And this is just a fraction of what you could do with RJS and Rails, while developing applications that use a lot of Ajax.

Did you like this? Share it: