The Blog

Rails + jQuery request datatypes condensed

Recently I’ve noticed that the default behaviour for the jQuery UJS adapter has changed a couple of times.

This is my condensed take on getting ajax working smooth with jQuery UJS and Rails 3

It seems a discussion has been taking place, determining how Rails 3 and jQuery’s default behavior would work the best. If you want in-depth understanding, I certainly recommend reading this really great article on the Alfa Jango blog, explaining the whole issue with thorough examples.

If you just want to copy paste and get on with what’s important to you, this post might be for you…

First off: I’m using rails 3.0.3 and jquery-rails 0.2.6, which in turn uses jQuery 1.4.4. I expect jQuery 1.5 will not affect the way jQuery UJS and Rails works together.

jQuery UJS has gone from defaulting to JS (resulting in a missing template error by default), through defaulting to anything (*/*) (resulting in rails returning the first format it finds available) to now accepting any format, but preferring JS. Let me show you how to utilize this.

In your view:

link_to "My ajax function", rails_path,
  :id => 'something-new', :remote => true

In your controller:

class SomeController < ApplicationController
  respond_to :html, :js

  def new
    respond_with(@some = Some.new, :layout => !request.xhr?)
  end
end

Now the respond_with will first try to render the new.js.erb file, and if that doesn’t exist, it will render the new.html.erb.
Note that the layout will not be rendered if this is an ajax call (:layout => !request.xhr?) – very neat.

For an in-depth view on respond_with, I can recommend Ryan Daigles post about that.

Or if you want to render an html partial only, you’ll have to respond explicitly to the JS format:

  def new
    respond_with(@some = Some.new) do |format|
      format.js { render :partial => "partial",
        :content_type => 'text/html', :layout => false }
    end
  end

And don’t forget to listen for the response on the client (if it’s html format) – in application.js:

$(document).ready(function(){
  $('#something-new').bind('ajax:success',
    function(evt, data, status, xhr){
    $('ul#things').append(xhr.responseText);
  })
});

Leave a Comment

Let us know your thoughts on this post but remember to place nicely folks!