Camel Punch - Brighton-based web development

jQuery and Rails. It's nothing special.

Why use jQuery anyway?

jQuery makes life easier for the site enhancement monkey. It's not always looked upon fondly by super geeks who like to split hairs over the benefits of particular programming practices.

For my money, the benefits of jQuery are:

  • You get a $() function that makes grabbing elements and adding functionality to any object dead simple
  • There are tonnes of plugins, and jQuery UI, which give you fancy hotness
  • It's not as ugly, and it's arguably more efficient, than Rails' built-in Prototype library

Be careful with code generation

I'd recommend that you don't try getting Rails to generate jQuery, or JavaScript in general. From my own experience, it's simpler and easier in the long-term to maintain well-structured 'pure' JavaScript files than it is to keep track of various Rails party tricks you can perform in view helpers. Plus, you get to look like a cool dude for keeping your JavaScript separate from your markup.

jQuery is extremely simple to use and is designed to take pain away - so don't fight it!

How I structure my JavaScript

I always turn 'caching' on for production mode by passing :cache => true to javascript_include_tag. This flattens all your JavaScript into one file, reducing browser GET requests and consequently the user's perceived load time. Make sure you get the order of your js files right - you want jQuery first, then any plugins, then your application code.

public/javascripts/application.js

Kicks off any functionality that's required when the DOM's ready. Instantiates classes or whatever. Sometimes holds quick hacks, or code for which I haven't yet found a home.

To start things off, use the following:

$(document).ready(function() { 
  // insert code here 
});

public/javascripts/class_name.js

From then on, I generally name JS files after the class name that I'm writing. Not sure I'm comfortable CamelCasing these files.

Patch jQuery for Rails' content negotiation

If you want to use format.js block to respond to requests made from jQuery's AJAX library, stick the following in your application.js:

jQuery.ajaxSetup({ 
  'beforeSend': function(xhr) {
    xhr.setRequestHeader("Accept", "text/javascript")
  } 
});

This is handy if you want to minimise URL mangling in JavaScript: you can just take the current location or form action and submit it to the server, safe in the knowledge that you will get a customised response specific for JavaScript requests.

Note that you might have better mileage using .json URLs to return JSON formatted data instead.

Use the form plugin

You'll find the jquery.form.js form plugin useful, because it allows you to submit an existing form as an AJAX request.

This is especially useful because Rails' default forgery protection requires form submissions to include an 'authenticity token'. Submitting the form as-is will include this automatically.

Note that similar functionality is included in Prototype, but the jQuery package does not include whole-form submission.

Update: latest jQuery doesn't need the form plugin so much

You can now do a $('form').serialize() to get a string version of all your form's elements.

The Rails action: success

Since we're RESTful and all that jazz, we'll reuse the code that does the creation when a normal form POST request is made. The only change is in the response: we'll just tell the browser that we made the resource and where it can be found.

def create
  # this assumes @cheese is already instantiated
 
  if @cheese.save
    respond_to do |format|
      format.html do
        redirect_to :index
      end
      format.js do
        head :created, :location => cheese_url(@cheese)
      end
    end
  else
    # something else for failure mode
  end
end

About the author

This tutorial's author is Andrew Bruce, who writes:

A friend working with me on BBC Introducing asked me to write this. So I did. An alternative title might be, "jQuery for Rails coders".