Section 3.1. Setting the Stage


3.1. Setting the Stage

For the examples in this chapter, we'll reuse the Rails application created in Chapter 2, but we'll generate a new controller. So back to the command line:

script/generate controller chapter3 get_time repeat reverse

That command generates a controller chapter3 with four actions: index, get_time, repeat, and reverse. Take a look at http://localhost:3000/chapter3 and you will see a bare-bones view, as in Figure 3-1.

Figure 3-1. New controller


In the previous chapter, we kept the example views as plain as possible. This time let's spruce it up a bit with an HTML layout and a CSS file. First create a new layout file, app/views/layouts/application.rhtml, and fill it with a basic XHTML template:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">   <head>     <title>Ajax on Rails</title>     <%= javascript_include_tag :defaults %>     <%= stylesheet_link_tag "application" %>   </head>   <body>     <h1>Ajax on Rails</h1>     <%= yield %>   </body> </html>

For our purposes, there are two important parts. The first is javascript_include_tag :defaults, which will include Prototype and script.aculo.us (specifically prototype.js, effects.js, dragdrop.js, and controls.js), as well as application.js, if present. The second is yieldthat's where the content from your action templates will be inserted. For the sake of nice-looking templates, let's make a simple CSS file, public/stylesheets/application.css:

body {   background-color: #eee;   color: #222;   font-family: trebuchet;   padding: 0;   margin: 25px; } h1 {   margin: -25px -25px 20px -25px;   padding: 50px 0 8px 25px;   border-bottom: 3px solid #666;   background-color: #777;   color: #fff;   font: normal 28pt georgia;   text-shadow: black 0px 0px 5px; } a { color: #229; } .box {   border: 1px solid;   width: 100px; height: 100px;   padding: 5px;   font-size: .6em;   letter-spacing: .1em;   text-transform: uppercase;   margin-bottom: 20px; } .pink {   border-color: #f00;   background-color: #fcc; } .green {   border-color: #090;   background-color: #cfc; } .hover {   border-width: 5px;   padding: 1px; } ul {   background-color: #ccc;   padding: 5px 0 5px 30px; }

With that in place, let's flesh out the controller a little. Edit app/controllers/chapter3_controller.rb, and define a few actions that we'll use later:

class Chapter3Controller < ApplicationController   def get_time     sleep 1.second     render :text => Time.now   end   def repeat     render :text => params.inspect   end   def reverse     @reversed_text = params[:text_to_reverse].reverse   end end

The next step is to make a basic view template, app/views/chapter3/index.rhtml. It's just a one-liner:

<%= link_to "Check Time", :action => 'get_time' %>

This uses the link_to helper introduced in the last chapter. The result of the helper is as simple as can be:

<a href="/chapter3/get_time">Check Time</a>

Refresh the page in your browser, and you should see something like Figure 3-2. Click the link, and the get_time action will render the current time in plain text.

Figure 3-2. Index template


The link_to helper takes a couple of options worth mentioning. First, the :confirm option allows you to add a JavaScript confirmation dialog box, so that the user can cancel an action before it proceeds. For example, suppose you have a link that triggers a potentially dangerous action:

<%= link_to "Fire missile", { :action => 'fire' },     :confirm => "Are you quite sure?" %>

With that modest protection in place, the user will have the option to click Cancel to halt the action.

Second, the :method option allows you to specify an HTTP method for the link:get, :post, :put, or :delete. Perhaps that option comes as a surpriseafter all, normal links can only use HTTP GET, and forms are only able to use GET or POST. So how does Rails pull off this trick? Well, it cheats. To see what I mean, create a link with the :method option like this:

<%= link_to "Delete", "/people/1", :method => :delete %>

If you view the source generated by the helper, you'll see something like this:

<a href="/people/1"    onclick="var f = document.createElement('form');            f.style.display = 'none';            this.parentNode.appendChild(f);            f.method = 'POST';            f.action = this.href;            var m = document.createElement('input');            m.setAttribute('type', 'hidden');            m.setAttribute('name', '_method');            m.setAttribute('value', 'delete');            f.appendChild(m);            f.submit(  );            return false;">Delete</a>

All that code hijacks the normal behavior of the link, so that when it's clicked, a hidden form is created on the fly and submitted behind the scenes. By itself, that hack just allows links to create POST requests. What about PUT and DELETE? To make those work, Rails piggybacks on the POST method. As you can see in the generated JavaScript, a field named _method is added to the hidden form. When Rails receives this parameter on the server side, it interprets the request as using that method.

The result is that with a little bit of hackery, it's easy to create links that take advantage of the full complement of HTTP methods. The rationale for using the correct HTTP methods is discussed in depth in Chapter 6.




Ajax on Rails
Ajax on Rails
ISBN: 0596527446
EAN: 2147483647
Year: 2006
Pages: 103
Authors: Scott Raymond

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net