Professional Documents
Culture Documents
Ruby on Rails 实践
Java 框架到底怎么了?
Ruby 简介:
Ruby 是由日本人松本行弘发明的一种面向对象的脚本语言。虽然很多语言都宣称自己是面
向对象的,但是每种语言的解释都不一样,大多是以它们自己特有的方式来解释什么是面向
对象,而实际情况中,这些面向对象语言又都采用了很多非面向对象的做法。以 Java 为例:
如果你想对一个数字取绝对值,你会怎么做呢? java 的做法是
int c = Math.abs(-166);
c = -166.abs
这种做法是不是更直观一点。
def hello(name)
result = "hello, " + name
return result
end
在 ruby 中,函数的最后一条语句如果是表达式,那么它就作为返回值。在上面的代码中,
用到了另外一个概念,就是表达式插入,字符串可以用单引号和双引号来括起来。但是两者
还是有一点区别。区别在于处理时间上的不同。如果使用单引号,那么处理的时间很短。如
果使用双引号,那么你可以插入变量,表达式,还有就是转意字符的替换,最常见的是 \n,
\t 等。 以上面的代码为例 字符串中插入了变量 name ,字符串中插入变量以 # 开始,变
量放在{}中。 但是特殊变量可以不用 {}. 那么什么是特殊变量呢。这个也是 ruby 特别的
地方。在 Ruby 中,全局变量以 $开头,静态变量,也就是类变量以 @@ 开头,实例变量
以 @ 开头。如果在字符串中引用 实例变量,你可以这么写。
def hello
" hello, #@name"
end
在 java 等语言中,我们的实现方法是:
for(int i = 1; i<6;i++) {
System.out.println(i);
}
而在 ruby 中,一切皆为对象,数字本身就是对象(我们在前面已经介绍过了),数字本身有
它自己的迭代器 times 。那么让我们看看它的实现。
6.times {|i| p i }
是不是很简单。
代码块和参数并不相同,它和函数的执行可以说是并行的,确切的说是接替进行。如果在函
数内部如何在运行过程中碰到了 yield ,它就会将函数执行过程交给函数附带的代码块来执
行,代码快执行完了,执行流程转到函数内部继续运行。似乎很难理解,以下面这段代码来
理解可以会容易一些。
def callBlock
yield
yield
end
yield a, b, c
这三个参数对应代码块中的三个参数 {|x,y,z| p x y z }
什么是 rails ?
安装 ruby
使用 rubygems 安装 rails
gem 命令包含很多子命令和相应的选项,比如
打开 DOS 命令行窗口,运行如下命令:
gem install rails –remote
安装 mysql 数据库和管理中心。
从 mysql.com 上下载 windows 版本的 mysql 服务器,本文章以 mysql 4.1 版本为例子(下
载地址为 http://dev.mysql.com/downloads/mysql/4.1.html).
默认设置安装 mysql , 在运行到结尾处安装程序会启动安装向导,在安装向导中需要设置
安全信息(用户名和口令)。由于 mysql 从 4.1.7 版本后采用了新的认证算法,这和老版本
的 rails 不兼容,所以网上教程不要求在这里设置用户名和口令。但是新版本的 rails 已经
解决了这个问题。本教程暂时不设置用户名和口令。
编写 rails 应用
总算到了这激动人心的一步了。
注明:以下示例大量参考了ONLamp.com (http://www.onlamp.com/) 上的 Ruby on rails 教程“ Rolling
任务简介:
我们所要完成的任务如下:
1:显示本人所搜藏的所有书籍
2:新增和编辑相应的书籍
3:将书籍指定不同的类别
D:\railsdoc>rails mybook
create
create app/apis
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 log
create public/images
create public/javascripts
create public/stylesheets
create script
create test/fixtures
create test/functional
create test/mocks/development
create test/mocks/test
create test/unit
create vendor
create Rakefile
create README
create CHANGELOG
create app/controllers/application.rb
create app/helpers/application_helper.rb
create test/test_helper.rb
create config/database.yml
create config/routes.rb
create public/.htaccess
create config/environment.rb
create config/environments/production.rb
create config/environments/development.rb
create config/environments/test.rb
create script/console
create script/console_sandbox
create script/destroy
create script/generate
create script/server
create script/runner
create script/benchmarker
create script/profiler
create script/breakpointer
create public/dispatch.rb
create public/dispatch.cgi
create public/dispatch.fcgi
create public/404.html
create public/500.html
create public/index.html
create public/favicon.ico
create public/javascripts/prototype.js
create doc/README_FOR_APP
create log/server.log
create log/production.log
create log/development.log
create log/test.log
D:\railsdoc>
你可以看到, rails 已经为你生成了 mybook 应用程序的完整目录结构。
Rails 不仅仅是一个运行时网络应用框架,它本身包含了丰富的脚本来帮你完成程序基本骨
架的工作。
启动 webrick 服务器如下:
Webrick 简介:
打开编辑器,编写以下脚本
require "webrick"
httpd = WEBrick::HTTPServer.new(
:DocumentRoot =>Dir::pwd + "/ruby",
:Port => 80
)
trap(:INT){ httpd.shutdown }
httpd.start
然后保存到 c:\server.rb 下,双击 server.rb , 一个最简单的 http server 就运行了,它将
c:\ruby 目录作为服务器文档根目录。
在浏览器窗口打开 http://127.0.0.1/
3:models 目录存放数据模型类,模型类封装了数据库中的数据。很多框架在数据模型层都做
的比较复杂,用过 rails 后,你会发现它非常容易使用。
编辑 controller 类
鼠标右键点击此文件,选择”edit” 打开编辑此文件。
在浏览器中访问 http://127.0.0.1:3000/My_Test/,
浏览器响应没有找到对应的 index 方法,不要担心,这不是什么大问题,因为默认生成的
控制器类,不包含任何方法。不过这里我们了解到,如果不输入任和 url 连接的话,默认
rails 需要在控制器类中找一个 index 的方法。这很容易理解,类似于 apache 服务器中目
录下面的 index.html 文件一样。
我们现在编辑这个 MyTestController 类。
如图:
保存文件后,在浏览器中运行 http://127.0.0.1:3000/My_Test/hello
这下你了解到 rails 是如何将 url 和控制器中的函数做简单映射的了吧。
这些默认规定的好处是:我不需要编辑复杂的配置文件,只要对相应的文件做编辑就可以了。我
们只需要关注程序逻辑,而不是其它什么,这就是 rails 设计原则中的“习惯约定优于配置”
。
创建 mybook 数据库
id int(11) 主键
title varchar(100)
description text
buydate date
3: 告 诉 rails 如 何 找 到 数 据 库 信 息 , 打 开 D:\railsdoc\mybook\config 目 录 , 编 辑
database.yml 配置文件。 ruby 程序喜欢用 yaml 作为配置文件,这种做法就象是 java 程
序喜欢用 xml 作配置文件一样,是传统习惯了。
新增内容:
YAML 简介:
很多初次接触 Ruby 的人可能会对它采用 yaml 文件作为配置文件感到奇怪。Yaml 库已经内置在 ruby 发
行版本中,做为很 “Ruby way”的方式用在各种读取配置的操作中。希望了解 Yaml 格式的人,可以参看
一下 http://www.yaml.org
• YAML 适合人们阅读
• YAML 适合与脚本语言交流
• YAML 使用宿主语言的内部数据结构
• YAML 拥有一致性的信息模型
• YAML 使基于流式数据的处理成为可能
• YAML 富于表达和可扩展
• YAML 容易实现
require ‘yaml’
tree = { :name => ‘ruby’,
:uses => [‘script’,’web’,’testing’,’etc’]
}
tree = YAML.load(File.open(“tree.yaml”)
tree[:uses][1]
输出结果: “web”
yaml 格式的一个大用途就是用在存储配置信息,因为它是纯文本格式的,非常适合阅读,同时又很适合
Ruby 等脚本程序将其读取到对象中。
下面就是个例子:
conf/config.yaml 文件内容如下:
host: 127.0.0.1
prefs:
username: mulder
password: trustno1
filename: xfiles
编辑 D:\railsdoc\mybook\app\controllers\ 下的 book_controller.rb
好了,魔法正式开场了。到现在我们还没有编写一行代码。如上所示
我们来测试一下,在浏览器中打开 http://127.0.0.1:3000/book/new
整个数据库表的登记界面已经为你做好了,你现在连 html 页面都没有打开过,这就是 rails
给我们带来的神奇之处。我们试着登记一些信息。
end
end
刷新浏览器页面
代码如下:
<html>
<head>
<title>All books</title>
</head>
<body>
</body>
</html>
我们重新编辑 book_controller.rb 文件
class BookController < ApplicationController
scaffold :book
def list
@books = Book.find_all
end
end
再次重新刷新页面
OK 了,现在我们很容易的定制了列表页面。
在这里稍微做一些解释:
@books = Book.find_all
这条语句告诉 rails ,调用 Book 模型类中的 find_all 函数从数据库表 books 中把所有记
录读出赋值到 @books 实例变量中。接着 rails 寻找 list.rhtml 以生成结果页面传递到浏览
器页面显示。在 list.rhtml 中
定义如下:
保存后,重新打开浏览器窗口,访问 http://127.0.0.1:3000/category/new
添加书籍类别数据
为了让 books 数据表包含类别字段,我们需要新增加一个 category_id 字段,字段定义为 int
型与 categories 表的 id 字段类型相同。
book.rb 修改如下:
category.rb 修改如下:
这两行申明就可以给我们生成在表关系之间导航的各种方法。例如,@book 变量中保存了
一本书的信息,我们想知道它属于的类别名,我就可以使用代码 @book.category.name , 再
比如,@category 保存了一个类别,我们想知道这个类别下有多少本书,那么我们可以通过
@category.books 来获得。
现在我们从新定义 edit 函数,来覆盖它的 scalffold 版本。
编辑 book_controller.rb 文件
class BookController < ApplicationController
scaffold :book
def list
@books = Book.find_all
end
def edit
@book = Book.find(@params["id"])
@categories = Category.find_all
end
end
<html>
<head>
<title>Edit book</title>
</head>
<body>
<h1>Edit book</h1>
<select name="book[category_id]">
<% @categories.each do |category| %>
<option value="<%= category.id %>"
<%= ' selected' if category.id == @book.category.id %>>
<%= category.name %>
</option>
<% end %>
</select></p>
</body>
</html>
<html>
<head>
<title>All books</title>
</head>
<body>
</body>
</html>
从新刷新浏览器内容(http://127.0.0.1:3000/book/list)
我们开始定义的三个任务已经完成。
关于 Ruby on rails 的思考(新增内容)
1: Rails 毕竟还没有大型项目的成功案例.
最近出现的个人目标管理网站 www.43things.com 是用 rails 制作的(国内的 www.aimi.cn
是用 asp 技术实现的),相信不久会有更多由 Rails 制作的网站出台。好的成功案例对一门
语言或技术来说是最好的广告,从当年 google 对 python 的推广就能看出来。
4:ruby 缺少组件的架构。
我觉得未来应用程序框架应该具备两个特点,那就是: “易用性”和“组件”。从现在的情形
看,Rails 具备了“易用性”的特点,而大多数 Java 框架具备了“组件”的特点。我觉得:
“好的框架的复杂性应该被组件封装在“黑箱”中,而“易用性”应该体现在组件的使用上”。
所以 Rails 的未来应该向组件上发展,而 Java 框架应该继续在组件易用性上多做文章,两
者的趋势是融合。
作者 Eiffel Qiu
Email: eiffelqiu@gmail.com
WWW: http://www.koalant.com
参考资源:(新增内容)
Ruby 网站资源:
引用的相关网站:
www.43things.com
www.aimi.cn (爱米网)
http://www.theserverside.com/articles/article.tss?l=RailsHibernate