基于 ROR 的网络订餐系统的设计与实现
摘 要 本文对最新 Web 应用 开发框架 Ruby On Rails 的工作原理做了简单介绍,讨论了
构建一个基于 ROR 的 Web 应用的实现 方法 和所用到的技术,并基于 ROR 开发了一个 网
络 订餐系统。 关键词 Rails;MVC;订餐系统;Web 1 引言 ROR 是 Ruby On Rails
的 英文 简称,ROR 是指使用 Ruby 语言实现的 Rails Web 开发框架。Ruby 是一种功能强
大的面向对象的、解释型的脚本语言。Ruby 语言具有下面几个特点: 语法简单、纯面向
对象语言、提供动态对象能力、使用单继承机制、操作符重载、迭代器和闭包、垃圾回收
、错误处理功能、拥有独立于操作系统的线程机制、可移植性高。 Ruby on Rails 是
一个使用纯 Ruby 语言编写的、实现了 MVC 模型的、易于开发、配置和管理的 Web 应用
程序的框架。 Rails 的设计思想由一组关键的概念来驱动:低重复(DRY)、约定优于配置
、 快速 Web 开发框架、对数据库访问的支持。 将( 模型-视图-控制器)MVC 模型用
于软件设计中可以使应用程序的构造更加清晰。Rails 是一个 MVC 框架。使用 Rails 开发
应用时,每个代码以及应用程序的每个部分都遵循标准的方式。也就是说,是在一个被事
先准备好的框架内开始应用程序设计的。 Rails 应用程序是由模块化的、面向对象的脚本
语言 Ruby 写成的,这些模块之间的相互链接和关系驱动着 MVC 模型的运行。
ROR 这些特点也使它逐步从一个开源和个人的 Web 开发框架走向主流,在诸多
Web 开发框架中以其鲜明的特色占据了一席之地。2007 年 12 月 6 曰, 发布,进
一步强化了对 企业 应用的支持。2 系统 分析 与设计 功能描述 基于 ROR 在开发应
用上的诸多优势,本文使用 ROR 开发了一个小型的网络订餐系统,根据客户要求,该系
统应具备下列主要功能: (1)向注册的客户提供可预订商品的列表和详细信息,供客户
选择。这些信息的维护由系统管理员进行。 (2)向客户提供一个订单提交、浏览和处理
界面,实现购物车形式的订餐功能。 (3)提供用户资料的管理功能,包括增加、删除和
信息修改。 (4)提供用户登录和权限控制功能,将为普通用户和系统管理员提供不同的
界面。 (5)提供商品和订单信息的查询功能、统计功能和打印功能。 系统选用数据库
作为后台数据库,运行环境为:Windows 2000 Server、Ruby 、Rails 、MySQL
。 使用 ROR 实现订餐系统的技术路线 1)将需求模块化 设计中将以递增式开发
这个应用程序,首先使用 Rails 立即创建具有一些功能的简单应用 myMealOrder。 系统
中开始只区分两种不同的角色:买方和卖方。买方使用 myMealOrder 来浏览站点可以出售
的商品,选择商品并创建一个订单。卖方使用 myMealOrder 来管理用于出售商品的列表,
并等待处理订单,然后将订单发货。 考虑到用户需要选择多项商品,系统中需要有地方
保存用户添加的产品列表的,所以在设计中添加了一个购物车。 2)使用 Rails 的“支架”
第一个任务是创建 Web 接口来管理系统中的商品信息---包括创建商品信息,编辑现有
商品,查看已有的商品信息,删除不需要的商品。为了实现以上功能,在数据库中应当建
立几张表,使用 Rails “支架”来自动生成最初的代码,这也是 Rails 具有敏捷性开发效率
的一个原因。 Rails“支架”是为管理一个“模型”而自动创建的一个框架。当运行“生成器”
时,告诉它需要“支架”来生成一个特殊的“模型”(由“支架”创建的),并且需要通过给定的“控
制器”(也是由“支架”创建的)来访问它。在 Rails 中,“模型”被自动地映射到使用“模型”的类
的名字的复数形式的数据库表。在应用程序中,根据需要要求有一个名为 good 的“模型”
,所以 Rails 将它与叫 goods 的表关联起来。 Rails 是如何找到这个表的呢?在
config/ 中设置 development 条目时,就已经告诉 Rails 在哪儿找数据库的表
了。当启动应用程序时,“模型”检查数据库内的表,处理它要得到的列,然后创建数据库
表和 Ruby 对象之间的映射。通过“支架”表单“生成器”可以向“模型”要求有关表的字段信息
,然后就使用它找到的字段来创建一个合适的 html 表单。 3)使用 Rails 的“控制器” “
控制器”处理来自浏览器的“请求”,一个应用程序可以有多个“控制器”。对于本次设计的
myMealOrder 应用程序来说,最终会有四个“控制器”,一个用于处理商品资料,一个用于
处理定单信息,一个用于用户资料,一个用于登录管理。 4)在生成的源码基础上根据需
要修改代码 scaffold 工具所生成的 Rails“支架”使用 Ruby 代码来组装应用程序目录树。
这个目录树表达了一个完整的应用程序构架—它的内部已经放置了 Ruby 代码;这些都是
源代码,而不是简单地对一些标准库的调用。这意味着可以修改“支架”内产生的代码,“支
架”是作为一个应用程序的起点,而不是应用程序的终点。开发者也可以对“支架”进行修改
,开发者依赖于“支架”生成器来产生创建,更新,删除的功能。然后在保留这个“动作”时
可以替换由生成器生成的行为。有时候当需要一个快速接口时,并且对界面要求不高,“
支架”就足够用了。 5)使用 Rails 的模型继承 “模型”层是代码与数据库之间的守护者,
应用程序访问数据库时没做任何事,或者将数据存回到数据库时也没有通过“模型”。那么
就把所有的确认工作放在模型里;不管数据的流向如何都不会有 问题 。如果在写到数据
库之前,“模型”检查它,就可以阻止损坏的数据到数据库中。“模型”类的源代码如下:(在
app/models/ 内)class Good<ActiveRecord::BaseEnd 看起来这什么都没做
,而数据库映射、创建、更新、搜索等行为都被父类(ActiveRecord::Base,Rails 的一
部分)完成了。由于继承的关系,Good 类 自然 地继承了所有父类的功能。 6)Rails 的动
态载入 在编辑完 文件后并没有重启应用程序来测试所做的修改——在开发模式
中,Rails 会注意到被修改的文件并重新加载它到应用程序中。 7)创建购物车模型 当
用户浏览订餐系统的在线分类目录时,他选择要购买的商品,系统约定每个被选择的产品
应该被添加到客户的虚拟购物车中,在有些时候,顾客会需要很多东西,并且他会给订餐
站点付款,为他购物车内的商品付款。这意味着应用程序将需要保持所有顾客选购到购物
车内的每个商品。 8)使用 session 功能 在浏览器与应用程序之间的协议是无状态的—
—没有内建的记忆。当应用程序接受来自浏览器的一个请求时,就如同是第一次被访问一
样,为了保存客户已放入购物车中的商品信息,系统在 Http“头”上加上一些有状态的事物
。应用程序内的某一层会试着对引入的请求,匹配它持有的本地“会话”数据部分。如果“会
话”数据的特定部分匹配来自特定浏览器的全部请求,系统会保存使用“会话”数据浏览器的
顾客买下的所有商品的轨迹。 9)定义数据表之间的关联 订单是一组商品项目,与购
买交易的细节。假定系统中已经有了商品项目,当创建新订单时,它必然要和一个或多个
商品项目联系在一起。在数据库中,这意味着系统需要从 line_items(存放购物车中商品的
信息)表到 orders(订单)表增加一个外键引用,所以在 line_items 表中定义外键:
Constraint fk_items_good forEign key(good_id) references good(id),constraint
fk_items_order forEIgn key(order_id)references orders(id),这告诉数据库外键的情况,因
为许多数据库都将检查外键约束,以保持代码的正确性。 10)定义模型之间的关系 系
统中需要告诉 Rails 一个订单有很多商品项目,并且一个商品项目属于一个定单。在
app/models 目录下新创建的 (订单模型)文件,添加一个对 has_many()的调用。然
后在 (购物车信息模型)文件中添加 belongs_to()方法的调用。 11)代码重用
假设已经有了一个有效的购物车,再创建一个新的 order 对象用来填充 view。注意这个
order 还没有保存到数据库—它只是用 view 来组装 checkout(订单信息表单)表单。可以在
checkout 页增加购物车 内容 的汇总。因为已经有了购物车显示页面的代码,接下来就可
以使用 Rails 的 componets 来重用购物车的显示代码。 网上订餐系统的具体实现
1) 创建数据库和表 首先在 Mysql 下创建了数据库 mydatabase,接着建立
orders 表,如图 1 所示。图 1 建立 orders 表 在这里,Rails 使用一种命名习惯,表名
都使用复数形式。Rails 可以识别这些复数表名和控制器、模型、视图之间的关系。Id 属
于系统在表中查找数据所必须的主键,是整型,非空且自增的,user_name 是用户的名字
,email 是用户的 email 地址,pay_type 是用户付款的方式,shipped_at 是餐厅送出商品
的时间,也就是交易完成的时间。 接下来修改 config 目录下面的 文件,
实现系统功能时所要修改配置的地方仅此一处。修改后的结果如下所示: development
: adapter: mysql database: mydatabase username: root password:
root socket: /path/to/your/ 其中 development 代表当前是处于开发模式
中,database:mydatabase 代表要连接的数据库名,username 和 password 分别为连接
数据库时所用到的用户名和密码。现在可以测试一下,打开命令行窗口输入 ruby
script/server 命令,然后打开浏览器,在地址栏中输入 http://localhost:3000/order
如图 2 所示。图 2 listing orders 的显示结果
在这里每条记录的修改、删除和详细信息的显示功能都有了,而且拥有了新增记录的功
能。同理可以建立如下的几张表和对应的控制器。经过 分析 ,系统现在需要一张商品表
,一张用户表。商品表用来存放网站所拥有的商品,用户表用来存放本网站的合法使用用
户。按照同样的步骤创建 goods 和 users 表。 goods 表中存放原来选择的食物列表,在
设计中没有使用 blob 类型的字段来存放真正的图片,如果这样做数据库的规模会非常庞
大,随着图片上传的数量增大,数据库的性能就可能会直线下降。在表中 image_url 中存
放的是图片的 url 地址,这个字段给 ROR 提供了一个图片地址的映射。当视图文件使用
ERB 和 HTML 语言填充页面时,获取图片是通过对 image_url 的引用来实现的。 2)
生成 应用 模板 Rails 提供了很多的帮助 方法 和工具,scaffold 工具就提供了生成
Controller(控制器)、Model(模型)和 View(视图)的功能。 打开命令行窗口,进入应用程序
目录,在其中输入 ruby script/generate scaffold 控制器名,就会在 views/控制器名目录
下生成 views 模板,包括 、、、 和 五
个视图文件,分别为数据库表的增删改查页面。系统中所用到的模板包括 user、order 和
good 三个,为了区分管理员和用户的页面,把 good 的 list 视图又划分为
和 ,然后对这些视图文件进行编辑修改,来定制自己的模板,
中是定制提取表中数据列的格式。 3) 商品管理的实现 图 3 是管理员登录时的界
面。图 3 商品管理页面 商品管理使用的 中的部分代码如下:class
GoodController < ApplicationController //声明 GoodController 继承
//ApplicationControllerbefore_filter :authorizemodel :cart //声明包含 cart 模型类
attr_reader :name //声明 name 属性为可读 def index @good =
_itemsenddef show_admin //显示详细信息 @good =
(params[:id])enddef show_user @good = (params[:id])enddef
new //新建商品项 @good = create //生成商品记录
@good = (params[:good]) if @ flash[:notice] = '食物记录已
成功创建.' redirect_to :action => 'list_admin' else render :action =>
'new' end enddef edit //编辑商品信息 @good = (params[:
id]) enddef update //修改已选中的数据 @good = (params[:id]) if
@_attributes(params[:good]) flash[:notice] = '食物记录已成功更新
.' redirect_to :action => 'show_admin', :id => @good else render :action
=> 'edit' end enddef destroy //删除数据 …… 4) 订单管理和查询
管理页面中的订单查询功能分为精确查找和模糊查找,精确查找是使用提交订单的用户
名和送餐日期进行复合查询。模糊查找只使用用户名进行查询。 订单管理页面提供该管
理员有关订单的详细信息,送货时间显示完成交易的最终时间,没有时间戳的订单表示没
有送出商品,管理员只能对订单进行删除操作,用户在结帐页面中提交的订单信息最终会
汇集这里。管理员可以对待发送商品的订单进行送货操作,这时会在订单的送货时间列中
加上一个时间戳。 5)购物车的实现(略)3 结论 网络 订餐系统的开发证明,使用 ROR
来开发一个中小型的 Web 应用是非常快速和便捷的,它和 J2EE Web 应用开发框架相比,
开发复杂程序大大减低,也不用处处使用 xml 语法来对应用进行配置;但 ROR 基于许多
约定和习惯来生成框架,而且对数据库设计有一些特殊的要求,一旦要在不符合约定和习
惯的旧有系统上进行更新设计,会使其快速开发的效率受较大的 影响 ,这是需要 ROR 后
续版本开发注意的方面。 参考 文献 [1]宋华,王佐成,汪林林.基于 RoR 框架的办公自动
化系统的设计 研究 ,微型电脑应用,2007 年 11 期[2]陈锵.Ruby on Rails 与 Struts 在应
用中的对比. 科技 资讯. 2007 年 6 期[3]高昂.面向 企业 的 Ruby on Rails.软件世界.2007
年 23 期