En un post anterior hablé un poco de cómo se siente codear en Coffeescript. Este pequeño tutorial trata acerca de los puntos básicos a la hora de hacer AJAX en Rails . Esta vez voy a usar un clásico: una aplicación de microblogging con soporte para crear blog posts y consideraré una función asincrónica para votarlos.

$ rm public/index.html
$ rake db:create
$ rails g resource post title:string name:string votes:integer
$ rake db:migrate

Ya tenemos una base en la que trabajar. Hay muchas maneras de lidiar con votos. Podés elegir usar un modelo para poder mantener seguimiento de los votos de un usuario, agregar la capacidad de remover un voto, limitar la cantidad de veces que un usuario puede votar en un misma acción de votación, etc. Pero voy a usar la forma más simple: una columna votes de la tabla Posts. Recomiendo usar ActiveRecord::Counter para actualizar el campo votes.

# app/controllers/posts_controller.rb
class PostsController < ApplicationController
  respond_to :html, :json

  def index
    respond_with @posts = Post.all
  end

  def vote_up
    @post = Post.find(params[:id])
    if @post.increment! :votes
      respond_with @post do |format|
        format.html { redirect :back }
      end
    end
  end
end

Vamos a necesitar agregar algunas rutas:

# config/routes.rb
MyBloggingApp::Application.routes.draw do
  root to: 'posts#index'
  resources :posts do
    member { post :vote_up }
  end
end

Y debajo tenemos una vista básica:

# app/views/posts/index.haml
.posts
  %h1 Listing posts

  - @posts.each do |post|
    %hr
    .post
      %legend
        = post.title
        %small{id: "#{post.id}_votes"}
          Votes: 
          = post.votes
      = link_to 'Vote_up', vote_up_post_path(post), class: 'vote_up', 'data-method' => :put, id: post.id
      = post.body.html_safe

Aqui tenemos un retazo de JS (Coffeescript) para implementar la votación asincrónica. Estamos enlazando la llamada AJAX al evento ‘click’ del botón para votar. Si el JS es desactivado o se encuentra un error de runtime, el boton va degradar de forma transparente a la acción html: votar y redirigir de vuelta.

# app/assets/posts.js.coffee
$ ->
  $('.post a.vote_up').click (ev)->
    ev.stopImmediatePropagation()
    ev.preventDefault() # If the javascript is enabled prevent default event (navigation)
    id = @id
    $.ajax
      url: "/posts/#{id}/vote_up.json",
      type: 'POST',
      complete: (data)-> # Update the 'Votes: X' field on success 
        post = JSON.parse(data.responseText)
        $("small##{id}_votes").text("Votes: #{post.votes}")

Si querés pegar una ojeada el código fuente para esta app se encuentra acá.
Más Info
jQuery.ajax() docs
David Parker’s blog post on Rails respond_to

Ruby on Rails developer at Altoros Argentina