Ruby on Rails is an online application framework that comes with Ajax support built in. Ruby is a stand-alone language that’s become popular in recent years, and Rails is the Web framework that allows you to put Ruby online.
On the Web | You can download Ruby on Rails for free from http://www.rubyonrails.com/down. |
Installing Ruby on Rails is easy: just follow the directions at http://www.rubyonrails.com/down. For example, there’s a handy one-click installer for Ruby for Windows at http://rubyinstaller.rubyforge.org. How much easier could it get than that? Just use the download link, and run the installing program. That’s it-you’ve got Ruby.
Setting up Rails in Windows is just about as easy. Just open a DOS command-prompt window and type this at the command prompt:
gem install rails --include-dependencies
And that’s it; you’ve got Ruby, and you’ve got Rails.
Installing on other platforms is as easy-or easier. For example, as of Mac OS X version 10.4, installation is more than easy: Ruby comes built in. To download Rails on the Mac, you’re going to need RubyGems, which you can pick up at http://docs.rubygems.org. After downloading RubyGems, go to the directory containing the download in the Terminal application and enter this at the command prompt:
tar xzf rubygems-0.8.10.tar.gz cd rubygems-0.8.10 sudo ruby setup.rb
The final step is to use RubyGems to download Rails, so enter this command:
sudo gem install rails --include-dependencies
That’s it; you should be on Rails.
If you’re using Linux or Unix, it’s probable that you already have Ruby installed (if not, take a look at www.rubyonrails.com/down). You’re also going to need Rails, which is most easily installed with RubyGems. To get RubyGems, go to http://docs.rubygems.org and click the downloads link. Then go to the directory containing the download and follow the directions described earlier for the Mac.
Time to take a look at a Ruby on Rails example. In the code that follows, the % sign stands for your command prompt, whether you’re using Windows, the Mac, or Linux/Unix. To start, you need to create a new Rails application, which is easily done. To create an application named Ajax, just enter this at the command prompt (in whatever directory you want to create the application):
%rails ajax
That makes Rails create the new Ajax application:
%rails ajax create create app/controllers create app/helpers create app/models create app/views/layouts create config/environments create components create db create doc create lib . . . create public/javascripts/prototype.js create public/javascripts/effects.js create public/javascripts/dragdrop.js create public/javascripts/controls.js create public/javascripts/application.js create doc/README_FOR_APP create log/server.log create log/production.log create log/development.log create log/test.log
Next, change directories to the new ajax directory:
%cd ajax
Now you create a controller named Look for the Ajax application; the controller handles the interaction with the user and routes the flow of the application to the correct parts of the application. Here’s how you create the controller:
%ruby script/generate controller Look exists app/controllers/ exists app/helpers/ create app/views/look exists test/functional/ create app/controllers/look_controller.rb create test/functional/look_controller_test.rb create app/helpers/look_helper.rb
Then you edit the file ajax\app\controllers\look_controller.rb, creating an action named at. Actions are called by the controller to execute specific tasks in Ruby on Rails applications. Add this code to look_controller.rb:
class LookController < ApplicationController def at end end
Now you can create the application’s view. The view is a Ruby-enabled HTML page with the extension .rhtml that users see in their browser. Create ajax\app\views\look\at.rhtml now, and place this code in it (you’ll see how this code works a little bit later in this chapter):
<html> <head> <title>Using Ajax</title> <%= javascript_include_tag "prototype" %> </head> <body> <h1>Using Ajax</h1> <br> <%= link_to_remote("Click me to use Ajax", :update => "displayDiv", :url => {:action => :replacer }) %> <br> <div id = "displayDiv">The new text will appear here.</div> </body> </html>
This code makes use of an action named replacer, so you need to add that action to the code in the file ajax\app\controllers\look_controller.rb. This action reads the text to download, so you set the :layout symbol to false here, indicating that you don’t want a page refresh:
class LookController < ApplicationController def at end def replacer render(:layout => false) end end
Finally, create the view for the replacer action, ajax\app\views\look\replacer.rhtml, and place this code in it:
This text was downloaded using Ajax.
To test this application, you can run the Web server that comes with Rails. To do that, you enter this command in the ajax application’s directory:
%ruby script/server
And this is what you see:
%ruby script/server => Booting WEBrick... => Rails application started on http://0.0.0.0:3000 => Ctrl-C to shutdown server; call with --help for options [2006-09-12 11:52:40] INFO WEBrick 1.3.1 [2006-09-12 11:52:40] INFO ruby 1.8.2 (2004-12-25) [i386- mswin32] [2006-09-12 11:52:40] INFO WEBrick::HTTPServer#start: pid=2304 port=3000
That starts the Rails Web server; to see what this application looks like in action, navigate your browser to http://localhost:3000/look/at, as shown in Figure 7.22, and then click the link. You should see the downloaded text, as shown in Figure 7.23.
Figure 7.22: A Ruby on Rails Ajax application
Figure 7.23: Downloading text with a Ruby on Rails Ajax application
How does this application do what it does? Here, you used Ajax to fetch text and display that text in a <div> element. You started by including the Rails prototype.js JavaScript library in the view where you want to use Ajax:
<html> <head> <title>Using Ajax</title> <%= javascript_include_tag "prototype" %> </head> <body> <h1>Using Ajax</h1> <br> <%= link_to_remote("Click me to use Ajax", :update => "displayDiv", :url => {:action => :replacer }) %> <br> <div id = "displayDiv">The new text will appear here.</div> </body> </html>
Now you can use link_to_remote to create a hyperlink that will fetch the results of an action and display them in a <div> element. To set up a hyperlink that displays the text Click me to use Ajax, updates the <div> element named displayDiv with the fetched data, and fetches the text to display from the replacer action, you call link_to_remote:
<html> <head> <title>Using Ajax</title> <%= javascript_include_tag "prototype" %> </head> <body> <h1>Using Ajax</h1> <br> <%= link_to_remote("Click me to use Ajax", :update => "displayDiv", :url => {:action => :replacer }) %> <br> <div id = "displayDiv">The new text will appear here.</div> </body> </html>
In HTML, this creates a call to the Rails prototype.js library function Ajax.Updater in the HTML code created after Rails processes the at.rhtml document:
<html> <head> <title>Using Ajax</title> <script src="/books/1/252/1/html/2//javascripts/prototype.js?1151422045" type="text/javascript"></script> </head> <body> <h1>Using Ajax</h1> <br> <a href="#" onclick="new Ajax.Updater('displayDiv', '/look/replacer', {asynchronous:true, evalScripts:true}); return false;">Click me to use Ajax</a> <br> <br> <h3><div id = "displayDiv">The new text will appear here.</div></h3> </body> </html>
The replacer action simply renders its output without including any layout, which means it just shows the text in the replacer action’s view, which is replacer.rhtml. Here’s what the replacer action looks like:
class LookController < ApplicationController def at end def replacer render(:layout => false) end end
And here’s the text that the replacer view returns, ajax\app\views\look\replacer.rhtml:
This text was downloaded using Ajax.
This is the text that will be displayed in the displayDiv <div> element. Here’s what the text in that <div> element starts off as:
<html> <head> <title>Using Ajax</title> <%= javascript_include_tag "prototype" %> </head> <body> <h1>Using Ajax</h1> <br> <%= link_to_remote("Click me to use Ajax", :update => "displayDiv", :url => {:action => :replacer }) %> <br> <h3><div id = "displayDiv">The new text will appear here.</div></h3> </body> </html>
Here’s what this page looks like in the browser after you’ve downloaded the text using Ajax:
<html> <head> <title>Using Ajax</title> <script src="/books/1/252/1/html/2//javascripts/prototype.js?1151422045" type="text/javascript"></script> </head> <body> <h1>Using Ajax</h1> <br> <a href="#" onclick="new Ajax. '/look/replacer', return false;">Click me to use Ajax</a> <br> <br> <h3><div id = "displayDiv">This text was downloaded using Ajax.</div></h3> </body> </html>
That’s a good start with Ajax and Ruby on Rails, but it’s only a start. Here, Rails handled the details for you, placing the downloaded text into the <div> element itself. But what if you want access to the Ajax data yourself? That’s coming up next.
You can configure link_to_remote to call a JavaScript function when your Ajax data is downloaded, which is more in line with the other Ajax frameworks described in this chapter. Here are the possible parameters to pass to link_to_remote to specify when you want your JavaScript function called:
:loading-The data is being loaded by the browser.
:loaded-The browser has finished getting the data.
:interactive-The user can interact with the data, even if it has not finished loading.
:success-The Ajax download is completed successfully.
:failure-The Ajax download failed.
:complete-The Ajax request is complete (whether it was successful or failed).
This next example uses the :success parameter to have a JavaScript function called with the downloaded data so you can handle that data in code. To start this new application, ajaxdata, create it this way:
%rails ajaxdata create create app/controllers create app/helpers create app/models create app/views/layouts create config/environments create components create db create doc create lib . . . create public/javascripts/prototype.js create public/javascripts/effects.js create public/javascripts/dragdrop.js create public/javascripts/controls.js create public/javascripts/application.js create doc/README_FOR_APP create log/server.log create log/production.log create log/development.log create log/test.log
then change directories to the ajaxdata directory:
%cd ajaxdata
and create a controller named Look for the ajaxdata application:
%ruby script/generate controller Look exists app/controllers/ exists app/helpers/ create app/views/look exists test/functional/ create app/controllers/look_controller.rb create test/functional/look_controller_test.rb create app/helpers/look_helper.rb
Now edit ajaxdata\app\controllers\look_controller.rb, adding this code to create an action named at:
class LookController < ApplicationController def at end end
Next, create the file ajaxdata\app\views\look\at.rhtml, and place this code in it, including a JavaScript function that will display the downloaded text in the <div> element in this Web page:
<html> <head> <title>Handling Ajax Data</title> <%= javascript_include_tag "prototype" %> <script language="JavaScript"> function handleData(request) { var displayDiv = document.getElementById("displayDiv"); displayDiv.innerHTML = request.responseText; } </script> </head> <body> <h1>Handling Ajax Data</h1> <br> <%= link_to_remote("Click me to handle Ajax data", :success => "handleData(request)", :url => {:action => :getter }) %> <br> <br> <h3><div id = "displayDiv">The new text will appear here.</div></h3> </body> </html>
then edit ajaxdata\app\controllers\look_controller.rb, adding this code to create the getter action:
class LookController < ApplicationController def at end def getter render(:layout => false) end end
Finally, create ajaxdata\app\views\look\getter.rhtml, and place this code in it:
This text was downloaded using Ajax.
Okay, that’s it; start the Rails Web server:
%ruby script/server => Booting WEBrick... => Rails application started on http://0.0.0.0:3000 => Ctrl-C to shutdown server; call with --help for options [2006-09-12 11:52:40] INFO WEBrick 1.3.1 [2006-09-12 11:52:40] INFO ruby 1.8.2 (2004-12-25) [i386- mswin32] [2006-09-12 11:52:40] INFO WEBrick::HTTPServer#start: pid=2304 port=3000
Open your browser and navigate to http://localhost:3000/look/at, as shown in Figure 7.24.
Figure 7.24: A Ruby on Rails Ajax application that lets you handle data
Then click the link; you should see the downloaded text, as shown in Figure 7.25.
Figure 7.25: A data-handling Ruby on Rails Ajax application
This Ruby on Rails example lets you set up a callback function to handle the downloaded data. The application starts by including the Rails prototype.js Ajax library in the view file, at.rhtml:
<html> <head> <title>Handling Ajax Data</title> <%= javascript_include_tag "prototype" %> <script language="JavaScript"> function handleData(request) { var displayDiv = document.getElementById("displayDiv"); displayDiv.innerHTML = request.responseText; } </script> </head> <body> <h1>Handling Ajax Data</h1> <br> <%= link_to_remote("Click me to handle Ajax data", :success => "handleData(request)", :url => {:action => :getter }) %> <br> <br> <h3><div id = "displayDiv">The new text will appear here.</div></h3> </body> </html>
In this example, you connected a successful download from an action named getter to a JavaScript function, handleData, which is passed the data sent to the browser from the getter action:
<html> <head> <title>Handling Ajax Data</title> <%= javascript_include_tag "prototype" %> <script language="JavaScript"> function handleData(request) { var displayDiv = document.getElementById("displayDiv"); displayDiv.innerHTML = request.responseText; } </script> </head> <body> <h1>Handling Ajax Data</h1> <br> <%= link_to_remote("Click me to handle Ajax data", :success => "handleData(request)", :url => {:action => :getter }) %> <br> <br> <h3><div id = "displayDiv">The new text will appear here.</div></h3> </body> </html>
In code, the getter action renders its view, without a layout:
class LookController < ApplicationController def at end def getter render(:layout => false) end end
The getter view passes this text data back to the browser:
This text was downloaded using Ajax.
In the browser, that text is stored in the XMLHttpRequest object’s responseText property, and that object is passed to the JavaScript handleData function like this, as the request parameter:
<html> <head> <title>Handling Ajax Data</title> <%= javascript_include_tag "prototype" %> <script language="JavaScript"> function handleData(request) { . . . } </script> </head> <body> <h1>Handling Ajax Data</h1> <br> <%= link_to_remote("Click me to handle Ajax data", :success => "handleData(request)", :url => {:action => :getter }) %> <br> <br> <h3><div id = "displayDiv">The new text will appear here.</div></h3> </body> </html>
You can display the text in a <div> element using code in the JavaScript handleData function:
<script language="JavaScript"> function handleData(request) { var displayDiv = document.getElementById("displayDiv"); displayDiv.innerHTML = request.responseText; } </script>
What does this action look like in HTML in the browser? Here it is:
<html> <head> <title>Handling Ajax Data</title> <script src="/books/1/252/1/html/2//javascripts/prototype.js?1151428997" type="text/javascript"></script> <script language="JavaScript"> function handleData(request) { var displayDiv = document.getElementById("displayDiv"); displayDiv.innerHTML = request.responseText; } </script> </head> <body> <h1>Handling Ajax Data</h1> <br> <a href="#" onclick="new Ajax.Request('/look/getter', {asynchronous:true, evalScripts:true, onSuccess:function(request){handleData(request)}}); return false;">Click me to handle Ajax data</a> <br> <br> <h3><div id = "displayDiv">The new text will appear here.</div></h3> </body> </html>
This is what gives you the result you see in Figures 7.24 and 7.25.