在Ruby on Rails中使用AJAX的教程

如果没有听说过 Rails,那么欢迎您外星旅行归来,近几年大概只有那个地方没有听说过 Ruby on Rails 了。Rails 最吸引人的地方是能够很快地建立功能完备的应用程序并运行起来。Rails 为 Ajax 而内置集成的 Prototype.js 库可以轻松快速地创建所谓的富 Internet 应用程序。

本文将逐步引导您创建 Rails 应用程序。然后深入分析如何利用 Ajax 特性编写从服务器上读写数据的 JavaScript 代码。
从容起步 Ajax 之旅——Ajax 技术资源中心

什么是 Ajax?Ajax(Asynchronous JavaScript and XML)是一种编程技术,它允许结合 XML 和 JavaScript 用于 Web 应用程序,从而打破页面刷新的范式,使您的用户快速方便的与 Web 应用程序交互。

您想了解如何构建基于 Ajax 的应用吗?developerWorks 中国网站上有非常多的关于 Ajax 的文章、教程和技巧,通过“Ajax 技术资源中心”,您可以非常快捷地找到能帮助您完成与 Ajax 相关的应用开发的技术参考资源。

关于 Rails 的一点说明

那么到底什么是 Rails 呢?Rails 是建立在 Ruby 编程语言上的一种 Web 应用程序平台。Ruby 存在大约有 10 年了。和 Perl 以及 Python 一样,它也是一种开放源码的敏捷编程语言,完全支持面向对象编程。

Rails 作为一种应用程序框架,强调使用正确的 Web 应用程序模式,即模型-视图-控制器(MVC)。在这里,系统的模型部分通常用一组映射到数据库表的 ActiveRecord 对象表示。控制器部分是一个 Ruby 类,其方法可以对模型执行各种操作。视图一般就是通过 ERB 模板(ERB 是 Ruby 内置的文本模板包)生成的超文本标记语言代码(HTML),形式上和 PHP 或 JavaServer Pages(JSP)代码生成的 HTML 类似。视图也可以是可扩展标记语言(XML)、文本、JavaScript 代码、图片或者其他东西。

用户从 Rails Web 应用程序请求页面时,URL 通过路由系统发送,后者将请求发送给控制器。控制器从模型请求数据并发送给视图完成格式化。

创建 Rails 应用程序时,系统自动生成一些目录和基本文件。包括随系统安装的 JavaScript 文件目录(包括 Prototype.js 库)、视图、模型和控制器目录,甚至还有存放从其他开发人员那里下载的插件的目录。

开始使用 Rails

创建 Rails 应用程序最简单的办法就是使用一个预先打好包的 Rails 系统。如果平台是 Microsoft? Windows?,建议您使用 Instant Rails。在 Macintosh 机器上我非常喜欢 Locomotive 2 应用程序。这些应用程序都包括 Rails 框架、Ruby 语言、Web 服务器和 MySQL。下载了这么多东西(确实是这样)之后,创建 Rails 应用程序仅仅是举手之劳了。

本文将创建一个新的菜谱应用程序,称为Recipe,只需要一个表。清单 1 显示了 Recipe 应用程序的数据库迁移。
清单 1. 数据库迁移

class CreateRecipes < ActiveRecord::Migration
 def self.up
 create_table ( :recipes, :options => 'TYPE=InnoDB' ) do |t|
 t.column :name, :string, :null => false
 t.column :description, :text, :null => false
 t.column :ingredients, :text, :null => false
 t.column :instructions, :text, :null => false
 end
 end

 def self.down
 drop_table :recipes
 end
end

数据库中只有一个表:recipes。包含五个字段:name、description、ingredients、instructions,还有一个字段是 Rails 基础设施自动维护的唯一标识符。

建立好数据库表之后,接下来就要为它包装一个 ActiveRecord 对象。该对象如 清单 2 所示。
清单 2. Recipe 模型

class Recipe < ActiveRecord::Base
 validates_presence_of :name
 validates_presence_of :description
 validates_presence_of :ingredients
 validates_presence_of :instructions
end

ActiveRecord 基类负责所有基本的数据库访问:查询表、插入、更新和删除记录。这里只要为每个字段增加验证就够了。我告诉 Rails 每个字段不能为空。

Ajax 表单

创建 Recipe 应用程序的第一步是向数据库中添加菜谱。首先介绍在 Rails 中创建基本 HTML 表单的标准方法。如 清单 3 中的 RecipesController 类所示。
清单 3. Recipes_controller.rb

class RecipesController < ApplicationController
 def add
 @recipe = Recipe.new
 if request.post?
 @recipe.name = params[:recipe][:name]
 @recipe.description = params[:recipe][:description]
 @recipe.ingredients = params[:recipe][:ingredients]
 @recipe.instructions = params[:recipe][:instructions]
 @recipe.save
 end
 end
end

只有一个方法 add,它首先创建一个空的 Recipe 对象。然后当客户机发出请求时添加参数并保存数据。

该页面的 ERB 模板如 清单 4 所示。
清单 4. Add.rhml

<html>
 <body>
<%= error_messages_for 'recipe' %><br/>
<%= start_form_tag %>
<table>
<tr><td>Name</td>
<td><%= text_field :recipe, :name %></td></tr>
<tr><td>Description</td>
<td><%= text_area :recipe, :description, :rows => 3 %></td></tr>
<tr><td>Ingredients</td>
<td><%= text_area :recipe, :ingredients, :rows => 3 %></td></tr>
<tr><td>Instructions</td>
<td><%= text_area :recipe, :instructions, :rows => 3 %></td></tr>
</table>
<%= submit_tag 'Add' %>
<%= end_form_tag %>
 </body>
</html>

页面首先显示 recipe 对象的错误消息。如果用户发布的数据没有通过 Recipe 模型对象的验证就会设置这些消息。然后依次为 <form> 标记、每个字段的 text_field 和 text_area 项、<submit> 标记和表单末尾。

这是非常标准的 Rails。安全可靠,可用于各种浏览器,清晰地映射到为客户机创建的 HTML。但我需要的是 Web 2.0,就是说 Ajax。那么,该如何修改呢?

控制器端的 add() 方法彻底变了,如 清单 5 所示。
清单 5. Recipes_controller.rb

class RecipesController < ApplicationController
 def add
 end

 def add_ajax
 Recipe.create( { :name => params[:recipe][:name],
 :description => params[:recipe][:description],
 :ingredients => params[:recipe][:ingredients],
 :instructions => params[:recipe][:instructions] } )
 end
end

add() 方法不再做任何事,因为有一个新的方法 add_ajax() 处理客户机返回的数据。

对于模板来说,不需要做大的修改,如 清单 6 所示。
清单 6. add.rhtml 的开始部分

<html>
 <head>
 <%= javascript_include_tag :defaults %>
 </head>
 <body>
 <div id="counter"></div>
<%= form_remote_tag :url => { :action => 'add_ajax' },
 :complete => 'document.forms[0].reset();',
 :update => 'counter' %>
<table>
<tr><td>Name</td>

文件开始在 HTML 中增加了 head 部分,其中包含对 Rails 默认 JavaScript 文件的引用。这就是 Prototype.js 系统,完成 Ajax 工作的大部分。

然后添加了 <div> 标记 counter,保存从 Ajax 请求返回的结果。并不是非常必要,但给用户一些反馈也不错。

最后,将原来的 start_form_tag 改为 form_remote_tag。form_remote_tag 有几个参数,其中最重要的是 url,它指定向何处发送数据。第二个是一个完整的处理程序,其中的 JavaScript 代码在 Ajax 请求完成时执行。这里重置表单以便让用户输入新的菜谱。然后使用 update 参数告诉 Rails 把 add_ajax 动作的输出发送到何处。

add_ajax() 方法还需要一个模板。如 清单 7 所示。
清单 7. Add_ajax.rhtml

<%= Recipe.find(:all).length %> recipes now in database

如此而已。但并不完全是。这仅仅是从标准 HTML 表单迁移到 Rails 中的 Ajax 表单。图 1 显示了准备提交的 Ajax 表单。
图 1. Ajax 表单

接下来是更加动态的交互,比如使用 Ajax 动态搜索。

Ajax 动态搜索

Prototype.js 提供了观察页面上的字段和表单的功能。我利用这种功能观察一个文本字段,可在其中输入部分菜谱名。然后运行 RecipesController 的搜索方法,输出放在文本字段下方的 <div> 标记中。首先从更新的 RecipesController 开始,如 清单 8 所示。
清单 8. Recipes_controller.rb

class RecipesController < ApplicationController
...
 def index
 end

 def search_ajax
 @recipes = Recipe.find( :all,
 :conditions => [ "name LIKE ?",
 "%#{params[:recipe][:name]}%" ] )
 render :layout=>false
 end
end

index() 方法呈现 HTML 表单。search_ajax() 方法根据搜索参数查找菜谱并把数据发送给 ERB 模板格式化。index.rtml 模板如 清单 9 所示。
清单 9. Index.rhtml

<html>
<head>
<%= javascript_include_tag :defaults %>
</head>
 <body>
<%= form_tag nil, { :id => 'search_form' } %>
<%= text_field 'recipe', 'name' %>
<%= end_form_tag %>

<div id="recipe">
</div>

<%= observe_form :search_form, :frequency => 0.5,
 :update => 'recipe',
 :url => { :action => 'search_ajax' } %>
 </body>
</html>

在 清单 9 的开头同样包括了 JavaScript 库。然后创建一个具有搜索字段和 <div> 标记的 form 表单用来保存搜索返回的数据。最后调用 observe_form() 辅助方法,它创建 JavaScript 代码观察表单的变化,并把表单数据发送到 search_ajax() 方法。然后将该方法的结果放到 recipe <div> 中。

search_ajax.rhtml 表单的代码如 清单 10 所示。
清单 10. Search_ajax.rhtml

<% @recipes.each { |r| %>
<h1><%= r.name %></h1>
<p><%= r.description %></p>
<% } %>

由于搜索结果可能有多项,循环遍历菜谱列表并输出其名称和说明。

当在浏览器中打开该站点并在地址栏中输入 apple 的时候,我找到了苹果馅饼的做法,如 图 2 所示。
图 2. Ajax 动态搜索

这就是最简单的实现。但如果希望进一步了解苹果馅饼该如何做?可以使用 Ajax 在需要时动态获得配料和做法吗?很高兴您这样问!当然能!


在命令中增加内容

有时候,让用户选择下载更多的信息而不是生硬地把信息堆到页面上更加友好。传统上,Web 应用程序开发人员使用隐藏的 <div> 标记包含信息,当用户要求这些资料时再显示出来。Rails 提供了一种更优美的方法,可以在需要的时候使用 Ajax 请求数据。

清单 11 中的菜单模板增加了 link_to_remote() 辅助方法调用。
清单 11. Search_ajax.rhtml

<% @recipes.each { |r| %>
<h1><%= r.name %></h1>
<p><%= r.description %></p>
<div id="extra_<%= r.id %>"></div>
<%= link_to_remote 'Extra',
 :url => { :action => 'get_extra_ajax', :id => r.id },
 :update => "extra_#{r.id}" %>
<% } %>

link_to_remote() 在页面中添加 JavaScript 代码和包含指定文本的 anchor(<a>)标记。客户单击该链接时,页面就会发出 Ajax 请求来获得新内容并替代原来的文本。

为了获得新的信息,必须为 RecipesController 添加一个 get_extra_ajax() 方法。如 清单 12 所示。
清单 12. Recipes_controller.rb

class RecipesController < ApplicationController
 ...
 def get_extra_ajax
 @recipe = Recipe.find( params[:id] )
 render :layout=>false
 end
end

此外还需要一个模板 get_extra_ajax.rhtml 来格式化这些信息。清单 13 显示了该模板。
清单 13. Get_extra_ajax.rhtml

<blockquote><%= simple_format @recipe.ingredients %></blockquote>
<p><%= simple_format @recipe.instructions %></p>

现在回到页面并输入 apple,将看到 图 3 所示的结果。
图 3. 增加了可以访问配料及做法的链接

单击该链接时,浏览器使用 Ajax 从 Web 服务器检索额外的资料并显示在那个位置。结果如 图 4 所示。
图 4. 菜谱的细节

如果有一个行项或细节类型的报告,这种 Ajax 模式非常方便,因为请求每个记录的细节可能非常耗时,最好在需要的时候再请求。此外这种技术也有助于节约屏幕资源。

可能最热门的 Web 2.0 特性是自动完成文本字段。否则 这趟 Ajax 之旅怎么能算完整呢?


自动完成字段

Rails 使得构建自动完成字段极其简单。首先要在 index.rhtml 模板中增加一些东西。修改后的版本如 清单 14 所示。
清单 14. 修改后的 index.rhtml

<html>
<head>
<%= javascript_include_tag :defaults %>
<style>
div.auto_complete {
 width: 300px;
 background: #fff;
}
div.auto_complete ul {
 border: 1px solid #888;
 margin: 0px;
 padding: 0px;
 width: 100%;
 list-style-type: none;
}
div.auto_complete ul li {
 margin: 0px;
 padding: 3px;
}
div.auto_complete ul li.selected {
 background-color: #ffb;
}
div.auto_complete ul strong.highlight {
 color: #800;
 margin: 0px;
 padding: 0px;
}
</style>
</head>
 <body>
<%= form_tag nil, { :id => 'search_form' } %>
<p><%= text_field 'recipe', 'name', :autocomplete => 'off' %></p>
<div class="auto_complete" id="recipe_name_auto_complete"></div>
<%= auto_complete_field :recipe_name,
 :url => { :action=>'autocomplete_recipe_name' },
 :tokens => ',' %>
<%= end_form_tag %>
...

文件上方的级联样式表(CSS)部分用于自动完成字段的下拉列表。此外还对 text_field 略做修改关闭浏览器的自动完成机制。下拉列表中的项放在新增的 <div> 中,这些项将调用 auto_complete() 方法。auto_complete() 辅助方法创建客户端 JavaScript 代码调用服务器上的 autocomplete_recipe_name() 方法以及 recipe name 文本字段的当前内容。

RecipesController 的 autocomplete_recipe_name() 方法搜索该名称,如 清单 15 所示。
清单 15. Recipes_controller.rb

class RecipesController < ApplicationController
...
 def autocomplete_recipe_name
 @recipes = Recipe.find( :all,
 :conditions => [ "name LIKE ?",
 "%#{params[:recipe][:name]}%" ] )
 render :layout=>false
 end
end

还需要一个 ERB 模板建立列表,如 清单 16 所示。
清单 16. Autocomplete_recipe_list.rb

<ul class="autocomplete_list">
<% @recipes.each { |r| %>
<li class="autocomplete_item"><%= r.name %></li>
<% } %>
</ul>

自动完成系统查找一个 HTML 列表(<ul>),其中每个列表项都是一个 option。使用 index.rhtml 页面的 CSS (或者您提供的样式表)格式化。

为了查看自动完成的效果,在浏览器中打开页面,然后输入 test。我在 test 菜谱中加入了一些数据。结果如 图 5 所示。
图 5. 下拉自动完成列表

可以使用上下箭头键选择一个选项然后按 Enter 键选择。这样将把选择的内容复制到文本字段中。

非常灵活,感谢 Rails 体系结构,它使这很容易实现。

结束语

无需讳言,我喜欢 Rails。从使用它的那一刻起我就被它深深吸引了。就我所见,Web 的很多开发人员都被它吸引了。为什么不呢?Rails 使得创建高交互性的 Web 应用程序易如反掌。

即使您还没有开始编写 Rails 应用程序,我也建议您下载 Instant Rails 或 Locomotive 应用程序开始尝试一下。您将体会到很多乐趣,并学习到很多可用于 Java? PHP 或 Microsoft .NET 应用程序的东西。也许您会发现您希望一直编写 Rails 代码。

(0)

相关推荐

  • 攻克CakePHP(PHP中的Ruby On Rails框架)图文介绍第1/2页

    CakePHP框架首页: http://www.cakephp.org/ 下载后导入工程中,目录结构如下图(使用版本:1.1.19.6305) 搭建PHP环境,这里使用了AppServ2.5.9. 下载主页 http://www.appservnetwork.com/ MySQL中新建数据库blog,并运行如下SQL文建表. /**//* First, create our posts table: */CREATE TABLE posts (    id INT UNSIGNED AUTO_I

  • ruby on rails 代码技巧

    git仓库输出 git archive --format=tar --prefix=actasfavor/ HEAD | (cd /home/holin/work/ && tar xf -) 输出到/home/holin/work/actasfavor/目录下 Posted by holin At May 16, 2008 16:42 加载plugins中的controller和model # Include hook code here require 'act_as_favor' #

  • ruby on rails中Model的关联详解

    前言: 在学习model关联之前,首先要牢记一下几点: 1.关联关系,两端都要写好,否则会出现初学者看不懂的错误.而且对于理解代码,非常有好处. 2.model的名字是单数,controller是复数. 3.blong_to后面必须是单数,而且必须是小写.has_many后面必须是复数. 一:一对多 例如: 王妈妈有两个孩子,小明和小亮.可以说,王妈妈,有多个孩子.也可以说:小明,有一个妈妈;小王,有一个妈妈.我们一般在设计表的时候,是这样设计的: mothers表中id和name sons表中

  • win7安装ruby on rails开发环境

    前言 看到很多文章都说ruby环境在windows上是非常难搭建,会出现各种各样的怪问题,所以都推荐到linux和mac上安装开发.但是我按照教程搭了下,问题也不算太多.总过大概花费了2个半小时左右就完成了.所以大家不要被吓尿了,下面就把安装的步骤及具体的版本记录了一下供大家参考. 安装步骤: 开发机环境:我使用的开发机:win7 旗舰版 - 64位 (cpu是i5). 1 安装 rubyinstaller-2.0.0-p481.exe     1 选择安装目录:(如:D:\server\Rub

  • Windows下Ruby on Rails开发环境安装配置图文教程

    本文详细介绍如何在Windows配置Ruby on Rails 开发环境,希望对ROR初学者能有帮助. 一.下载并安装Ruby Windows下安装Ruby最好选择 RubyInstaller(一键安装包). 下载地址: http://rubyforge.org/frs/?group_id=167 . 我们这里下载目前较新的rubyinstaller-1.9.3-p0.exe 一键安装包.这个安装包除了包含ruby本身,还有许多有用的扩展(比如gems)和 帮助文档. 双击安装,安装过程出现如下

  • CentOS中配置Ruby on Rails环境

    详细安装步骤: 一.更新Python centos 中默认安装的python是2.4的版本,因为新版的rails需要提供nodejs的相关支持,需要更新python,更新文章可以直接移步到这个链接 http://www.tomtalk.net/wiki/Python 复制代码 代码如下: yum install -y bzip2*           #nodejs 0.8.5需要,请安装python前,先安装此模块.   wget http://www.python.org/ftp/pytho

  • 在阿里云 (aliyun) 服务器上搭建Ruby On Rails环境

    1.阿里云的一键安装web全环境 下载一键安装web全环境 sh.zip 压缩包 上传至服务器,解压.执行脚本,具体步骤详见这里 $ mv sh.zip /home/tmp/ & cd /home/tmp $ unzip sh.zip $ chmod -R 777 sh & cd sh # 任意选择一种方法执行脚本 # 方法一 $ ./install.sh # 方法二 $ ./install_nginx_xxx.sh $ ./install_mysql_xxx.sh 2.安装RVM与指定的

  • 在Ruby on Rails中使用AJAX的教程

    如果没有听说过 Rails,那么欢迎您外星旅行归来,近几年大概只有那个地方没有听说过 Ruby on Rails 了.Rails 最吸引人的地方是能够很快地建立功能完备的应用程序并运行起来.Rails 为 Ajax 而内置集成的 Prototype.js 库可以轻松快速地创建所谓的富 Internet 应用程序. 本文将逐步引导您创建 Rails 应用程序.然后深入分析如何利用 Ajax 特性编写从服务器上读写数据的 JavaScript 代码. 从容起步 Ajax 之旅--Ajax 技术资源中

  • Ruby和Ruby on Rails中解析JSON格式数据的实例教程

    Ruby解析JSON Ruby解析Json例子: json = '["a", "B", "C"]' puts "Unsafe #{unsafe_json (json).inspect}" #输出Unsafe ["a", "B", "C"] Ruby解析Json把上面的json字符串解析成Array.这样的方法并不安全,比如: json = 'puts "Da

  • django中的ajax组件教程详解

    Ajax(Asynchronous Javascript And XML)翻译成英文就是"异步Javascript和XML".即用Javascript语言与服务器进行异步交互,传输的数据为XML,(现在使用更多的是json数据). 向服务器发送请求的途径 1.浏览器地址栏 http://www.baidu.com 默认是get请求 2.form表单发送请求: GET请求 POST请求 3.a标签 href属性 默认是get请求 4.ajax() Ajax的特点 异步交互:客户端发送一个

  • 在Ruby on Rails中使用Rails Active Resource的教程

    简介 当今的应用程序不仅需要和基于浏览器的客户端互操作,还需要和其他应用程序互操作.为实现互操作性,web 应用程序通常提供一个 web 服务 API.web 服务 API 通过一个网络(比如 Internet)提供对应用程序 的远程访问.直到最近,web 服务 API 还使用重型.复杂的基于 SOAP 的 web 服务集成,这种 web 服务,不仅没有什么优点,而且还需要很长时间才能实现.带有基于 Representational State Transfer (REST) 服务的 Rails

  • Ruby on Rails中MVC结构的数据传递解析

    如果读者已经开发过基于 Rails 的应用,但对其 MVC 间的数据传递还有诸多困惑,那么恭喜您,本文正是要总结梳理 Rails 数据传递的方法和技巧.Ruby on Rails 3(以下统称为 Rails 3)是当前的主要发布版本,本文所述及的内容和代码都基于此版本. Rails 3 简介 Ruby on Rails 是一个 Ruby 实现.采用 MVC 模式的开源 Web 应用开发框架,能够提供 Web 应用的全套解决方案.它的"习惯约定优于配置"的设计哲理,使得 Web 开发人员

  • 在Ruby on Rails中优化ActiveRecord的方法

    Ruby on Rails 编程常常会将您宠坏.这一不断发展的框架会让您从其他框架的沉闷乏味中解脱出来.您可以用习以为常的几行代码片断表达自己的意图.而且还可以使用 ActiveRecord. 对于我这样的一个老 Java? 程序员而言,ActiveRecord 多少有点生疏.通过 Java 框架,我通常都会在独立的模型和模式之间构建一种映射.像这样的框架就是映射框架.通过 ActiveRecord,我只定义数据库模式:或者用 SQL 或者用称为迁移(migration)的 Ruby 类.将对象

  • 深入理解Ruby on Rails中的缓存机制

    几个场景 首先,让我先来带您浏览几个 ChangingThePresent.org 中的页面吧.我将显示站点中几个需要缓存的地方.然后,再指出我们为其中每个地方所做出的选择以及为实现这些页面所使用的代码或策略.尤其会重点讨论如下内容: 全静态页面 几乎无变化的全动态的页面 动态页面片段 应用程序数据 先来看看静态页面.几乎每个站点都会有静态页面,如图 1 所示,其中还有我们的条款和条件.可以通过单击 register 然后再选择是否接受用户协议来浏览相应页面.对于 ChangingThePres

  • 利用RJB在Ruby on Rails中使用Java代码的教程

    开始之前 关于本教程 Ruby on Rails (Rails) 是用 Ruby 编写的一个 full-stack Web 应用程序框架,而 Ruby 是一种功能丰富的.免费的.可扩展的.可移植的.面向对象的脚本编制语言.Rails 在 Web 应用程序开发人员之间非常流行.通过它,可以快速有效地开发 Web 应用程序,并将其部署到任何 Web 容器中,例如 IBM? WebSphere? 或 Apache Tomcat. 在 Rails 和类似的 Web 应用程序开发框架出现之前,用于 Web

  • Ruby On Rails中如何避免N+1问题

    N+1问题 N+1问题是数据库访问中最常见的一个性能问题,首先介绍一下什么是N+1问题: 举个例子,我们数据库中有两张表,一个是Customers,一个是Orders.Orders中含有一个外键customer_id,指向了Customers的主键id. 想要得到所有Customer以及其分别对应的Order,一种写法是 SELECT * FROM Customers; 对于每一个Customer: SELECT * FROM Orders WHERE Orders.customer_id =

随机推荐