Rails 3.1預設的JavaScript程式庫是jQuery,在 版型(Layout) 中看過,預設會包括jquery.js,而一些頁面的「神奇魔法」,則是由jquery_ujs.js來處理與銜接jQuery,例如 版型(Layout)中介紹過,以link_to輔助方法為例,在按下其產生的鏈結時,會執行jquery_ujs.js中的程式碼,動態建立表單並使用表單物件的submit發送:
    // Handles "data-method" on links such as:
            // <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a>
            handleMethod: function(link) {
              var href = link.attr('href'),
                method = link.data('method'),
                target = link.attr('target'),
                csrf_token = \$('meta[name=csrf-token]').attr('content'),
                csrf_param = \$('meta[name=csrf-param]').attr('content'),
                form = \$('<form method="post" action="' + href + '"></form>'),
                metadata_input = '<input name="_method" value="' + method + '" type="hidden" />';
        
              if (csrf_param !== undefined && csrf_token !== undefined) {
                metadata_input += '<input name="' + csrf_param + '" value="' + csrf_token + '" type="hidden" />';
              }
        
              if (target) { form.attr('target', target); }
        
              form.hide().append(metadata_input).appendTo('body');
                form.submit();
              },
      
handleMethod是以submit發送表單,也就是所謂同步表單或非Ajax表單,有些輔助方法可以設定:remote => true,此時就會以非同步方式來發送,也就是所謂Ajax方式,以link_to輔助方法為例,若加上:remote => true,則產生的超鏈結會加上data-remote="true"(form_for、button_to等也有:remote可以設定)。例如:
<a href="/messages/1" data-remote="true">Show</a>
      
標記為data-remote="true"的鏈結,會使用handleRemote方法處理,簡單來說,就是以非同步物件發送:
      
    // Submits "remote" forms and links with ajax
            handleRemote: function(element) {
              var method, url, data,
                crossDomain = element.data('cross-domain') || null,
                dataType = element.data('type') || (\$.ajaxSettings && \$.ajaxSettings.dataType),
                options;
                ...
        
                options = {  
                 ....略
                };
                // Only pass url to `ajax` options if not blank
              if (url) { options.url = url; }
                return rails.ajax(options);
              } else {
                return false;
              }
            },
      
按下鏈結之後,由於是非同步回應,所以不會換頁,你要根據回應自行處理畫面,預設收到的回應是JavaScript,也可以指定JSON等其它格式。
舉例來說,可修改 觀摩 Scaffold 中的index.html.erb如下:
- index.html.erb
<h1>Listing messages</h1>
<div id="message"></div>
<table>
  <tr>
    <th>Name</th>
    <th>Title</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>
<% @messages.each do |message| %>
  <tr>
    <td><%= message.name %></td>
    <td><%= message.title %></td>
    <td><%= link_to 'Show', message, :remote => true %></td>
    <td><%= link_to 'Edit', edit_message_path(message) %></td>
    <td><%= link_to 'Destroy', message, confirm: 'Are you sure?', method: :delete %></td>
  </tr>
<% end %>
</table>
<br />
<%= link_to 'New Message', new_message_path %>
如此按下Show鏈結就不會換頁,而會以非同步方式發送請求,接著可以修改messages_controller.rb:
- messages_controller.rb
class MessagesController < ApplicationController
  ...
  def show
    @message = Message.find(params[:id])
    respond_to do |format|
      format.html # show.html.erb
      format.js   # show.js.erb
      format.json { render json: @message }
    end
  end
  ...
end
非同步請求預設希望取得JavaScript回應,否則取得HTML回應,如上設定之後,若有個show.js.erb:
- show.js.erb
\$('#message').html("<p><b>Content:</b><%= @message.content %></p>")
             .css({ backgroundColor: '#ffff99' });
接下來如果按下Show鏈結,就會在同頁面中<div id="message"></div>載入訊息內容。
如果想取得的回應是JSON格式,例如:
- index.html.erb
<h1>Listing messages</h1>
<div id="message"></div>
<table>
  <tr>
    <th>Name</th>
    <th>Title</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>
<% @messages.each do |message| %>
  <tr>
    <td><%= message.name %></td>
    <td><%= message.title %></td>
    <td><%= link_to 'Show', message_path(:id => message, :format => :json), :remote => true %></td>
    <td><%= link_to 'Edit', edit_message_path(message) %></td>
    <td><%= link_to 'Destroy', message, confirm: 'Are you sure?', method: :delete %></td>
  </tr>
<% end %>
</table>
<br />
<%= link_to 'New Message', new_message_path %>
<script>
  \$(function() {
    \$('a[data-remote]').bind("ajax:success", function(event, data) {            
      \$('#message').html('<p><b>Content:</b>' + data.content + '</p>')
                   .css({ backgroundColor: '#ffff99' });
      });
  });
</script>
按下Show鏈結,就會在同頁面中<div id="message"></div>載入訊息內容。
Rails 3中基本上對Ajax沒有提供太多神奇的魔法,DHH建議自己要親自撰寫JavaScript來處理一些事,這意謂著你對Ajax必須有更多的瞭解,你要嘛將JavaScript放在伺服端,結合Erb之類的來輔助產生內容,要嘛將JavaScript放在客戶端,並與伺服端協定好資料格式,或必要時撰寫一些頁面輔助方法來簡化頁面與伺服端的溝通。
如果要提供JSONP,只要在render時指定:json與:callback即可。例如:
- messages_controller.rb
class MessagesController < ApplicationController
  ...
  def show
    @message = Message.find(params[:id])
    respond_to do |format|
      format.html # show.html.erb
      format.js   # show.js.erb
      format.json { render json: @message, :callback => params[:callback] }
    end
  end
  ...
end
如果使用者指定請求參數callback=process_message,則一個回應範例如下:

