Veerasundaravel's Ruby on Rails Weblog

November 18, 2011

link_to_remote With Rails 3 and UJS

Filed under: Rails3 — Tags: , , , , , , , — Veerasundaravel @ 3:46 pm

Rails 3 has adopted Unobtrusive Javascript and moved all the _remote functions to a plugin called prototype_legacy_helper. You can view the release note about this here. They did this in an effort to remove all the inline nasty code produced by the helpers and provide a more modular way to deal with Javascript & Ajax.

What this means is that all previous remote_<method> helpers have been removed from Rails core. To get UJS hooks into your HTML, you can now pass :remote => true instead. For example:

in Rails2:

link_to_remote('Refresh', :update => "emails", :url => {:controller=>"mail", :action => "list_emails" })

#will result

<a href="#" onclick="new Ajax.Updater('emails', '/mail/list_emails', {asynchronous:true, evalScripts:true}); 
return false;">Refresh</a>

 

in Rails3:

link_to 'Refresh', {:controller=>"mail", :action => 'list_emails'}, :remote=> true 

#will result

<a href="/mail/list_emails" data-remote="true">Refresh</a>

This makes it very easy for a javascript driver to come along, pick out and identify the relevant pieces, and attach the appropriate handlers.

Grab the jQuery UJS driver at http://github.com/rails/jquery-ujs and put it in your javascripts directory. The file is at src/rails.js

Include jQuery and the UJS driver in your application layout or view. Then the Rails UJS driver look for links and forms with a data-remote=”true” attribute and AJAX-ify them. So now our <a> tag can fire a Ajax request.

 

Ajax Callbacks:

With good old link_to_remote we could pass an :update option to achieve the system described above, in which the page receives a generic response and updates the specified element with it. But link_to doesn’t accept an :update option because with Rails 3 and UJS we want to avoid putting JavaScript in our <a> tag attributes.

So how do we do this? If we don’t write the code that makes the AJAX request, how can we access the response? The answer is: events.

 

The UJS drivers trigger six events on every AJAX call:

  • ajax:before
  • ajax:loading
  • ajax:success
  • ajax:failure
  • ajax:complete
  • ajax:after

You should recognize these event names from the old link_to_remote method options, and we simply need to listen for them on our AJAX-triggering elements.

 

Example:

Let’s say we have a page that lists the ten most popular products in our database. At the end is a link to load all the remaining products via AJAX:

<ul id="products-list">
  <li>...</li>
  <li>...</li>
  <li>...</li>
 ...
</ul>
<%= link_to "more...", "/products/all", :id => "load-more", :remote => true %>

The server returns plain HTML and we use the ajax:x events triggered by the Rails UJS drivers (here jQuery) to grab the server’s response and insert it into the right element on the page:

<%= javascript_tag do %>
  $("#load-more").bind("ajax:complete", function(et, e){
    $("#products-list").html(e.responseText); // insert content
  });
<% end %>

If desired, we can also use the ajax:loading event to change the link text (or show a spinner):

<%= javascript_tag do %>
  $("#load-more").bind("ajax:loading", function(et, e){
    $(this).html("Loading..."); // swap link text
  });
<% end %>

 

Use the forgery protection meta tags: <%= csrf_meta_tag %>:

This tag will return meta tags with the cross-site request forgery protection token for forms to use. Place this in your head, it will return meta tags as follows:

<metaname="csrf-param"content="authenticity_token"/>
<metaname="csrf-token"content="pACcWm38PxTmGUoz2bSmKIzIwpEmqCJDTH6xe2="/>

Don’t hardcode these tags or values. Also in Rails 3.1, csrf_meta_tag has been renamed to csrf_meta_tags.

About these ads

5 Comments »

  1. Neat explanation!

    Comment by Srikanth Jeeva — November 18, 2011 @ 5:03 pm

  2. [...] link_to_remote With Rails 3 and UJS (veerasundaravel.wordpress.com) [...]

    Pingback by Render Vs. Redirect_to in Rails | The Physical Dangers Of Working With Code — January 3, 2012 @ 8:45 am

  3. Big Thanx)

    Comment by alvisx — July 21, 2012 @ 7:08 pm

    • You are welcome and thank you for referring the blog.

      Comment by Veerasundaravel — July 21, 2012 @ 9:46 pm

  4. Very great post. I simply stumbled upon your weblog and
    wished to mention that I have truly loved surfing around your blog
    posts. In any case I will be subscribing for your feed and I’m hoping you write again soon!

    Comment by seo places — May 17, 2013 @ 2:16 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Silver is the New Black Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 120 other followers

%d bloggers like this: