锻造坊 - Ruby on Rails
Ruby 是一种解释型编程语言,其外观和感觉像是 Smalltalk 和 Perl 的混合体,已经存在大约十年了。Ruby 在过去几年中越来越受欢迎,部分原因是英文书籍和文档的发布。此外,程序员对寻找 Perl 和 Python 的替代品以满足其通用编程需求越来越感兴趣。
如果不是因为 Ruby on Rails 这个 Web 开发框架引起了巨大的关注,Ruby 的普及率可能会继续缓慢增长。Web 开发领域的每个人似乎都在谈论 Rails;杂志文章、博客帖子、会议议题,甚至一些新书都专门介绍 Rails。Rails 被认为是优雅、易于使用和易于修改的。即使是没有 Ruby 经验的开发人员也在转向 Rails。
Rails 是否名副其实?在很大程度上,我认为答案是“是”——它具有相对较浅的学习曲线,它可以轻松快速地连接到关系数据库,并且与我预期的相比,它可以更快更轻松地创建许多中小型站点。但是,当然,没有哪个框架是完美的,尤其是对于一个仅在一年前公开发布的框架而言。Rails 是否能在几个不同的方面经受住更成熟技术的考验,还有待观察。
本月,我们将开始研究 Ruby on Rails 的几个方面,以便您可以自己判断我的评估是否准确。我们首先安装和配置一个基本的 Rails 应用程序。在接下来几期“锻造坊”中,我们将以几种不同的方式扩展我们的应用程序,考虑 Rails 允许我们创建和修改应用程序的方式。
创建 Rails 应用程序的第一步是安装 Ruby,然后再安装 Rails 本身。大多数现代 Linux 发行版都带有 Ruby,但截至本文撰写时,只有最新发布的版本 (1.8.2) 才能与最新版本的 Rails (0.12.1) 配合使用。Rails 的新版本一直在频繁发布,这意味着当您阅读本文时,这两个版本中的一个或两个可能已经更改。
假设您已经安装了 Ruby,接下来您需要安装 Gems。它提供了对 Ruby Gems 库的访问,该库有点像 SourceForge 和 Perl 的 CPAN 的混合体(请参阅在线资源)。下载并解压最新的 .tar.gz 文件
tar -zxvf rubygems-0.8.10.tar.gz
以 root 用户身份进入该目录并键入
ruby setup.rb all
这将安装整个 Gems 包。 除此之外,这还在 /usr/bin 中安装了 gem 程序。然后,您可以使用以下命令安装通过 Gems 分发的 Rails
gem install --remote rails
与 CPAN 和 Debian 的 apt 等系统一样,gem 程序足够智能,可以识别和下载它可能遇到的任何依赖项。 默认情况下,当询问您是否有兴趣安装任何依赖项时,您需要显式回答“y”。 由于 Rails 依赖于许多其他软件包,因此您应确保在出现提示时回答“y”。
当您返回到 shell 提示符时,您可以认为 Rails 已安装。但是,这还远远不够。如果您有兴趣使用关系数据库,则还需要安装数据库接口库。因为我使用 PostgreSQL,所以我安装了纯 Ruby 客户端,名为 postgres-pr
gem install --remote postgres-pr
有些令人困惑的是,还有一组 PostgreSQL 客户端库(名为 postgresql)可以与 Ruby 一起使用。但是,似乎大多数 Rails 开发人员都在使用 postgres-pr 库,至少目前是这样。
安装 Rails 后,我们可以创建一个简单的“Hello, world”程序。为此,我们使用rails命令,该命令默认安装在 /usr/bin/ 中。由于我们的示例应用程序是一个 Weblog,因此我们调用应用程序 blog。作为参考,应用程序的名称不必链接到它将出现的 URL 的名称。键入
rails blog
运行此命令会产生大量输出,列出已在我们的文件系统上创建的文件。当我们只给出一个名称 blog 时,应用程序将在具有该名称的目录中创建。我们可以将所有应用程序保存在单个容器目录中,例如 ~/Rails,使用
mkdir ~/Rails rails ~/Rails/blog
如果我们查看新创建的应用程序目录内部,我们会看到许多目录和文件。 script 目录包含管理程序,当然是用 Ruby 编写的。 public 目录包含静态 HTML 文件,以及您可以在应用程序中使用的图像、样式表、JavaScript 代码和模板。
您最有可能使用的目录是 app,它包含应用程序本身。 app 目录包含名为 models、views 和 controllers 的子目录。此设计反映了 Rails 使用 MVC(模型/视图/控制器)风格的事实,该风格广泛用于许多现代桌面和 Web 应用程序中。
在 MVC 架构中,我们将工作分为三个部分——控制器,它充当交换机,调用适当的模型和视图;模型,它包含数据和一些逻辑;以及视图,它向用户显示信息。如果您曾经使用 PHP 和 Smarty 模板或 Zope 及其 Page Templates 甚至 Java 和 JavaServer Pages (JSP) 构建过数据库支持的站点,那么您已经熟悉其中至少一些想法。Rails 只是通过其预先命名的目录结构使它们更加明确。
虽然它不能做太多事情,但我们现在可以使用以下命令启动我们的空 Rails 应用程序
cd ~/Rails/blog ruby script/server
这将在端口 3000 上启动 WEBrick HTTP 服务器。要访问这个相当空的 Rails 站点,我们将浏览器指向适当的 IP 地址或主机名。在我的特定情况下,我在我的测试服务器上启动了 Rails,其 IP 地址为 192.168.2.3。因此,我将 Web 浏览器指向 http://192.168.2.3:3000/。果然,我看到了“Welcome on board”消息,表明我已正确设置 Rails。
既然我们知道如何查看默认消息,让我们转向“Hello, world”程序。在 Rails 中,有两种基本方法可以做到这一点。我们可以创建一个控制器,将 HTML 返回给用户的浏览器,或者我们可以创建一个视图来做同样的事情。让我们两种方法都尝试一下,以便我们可以更好地理解控制器和视图之间的关系。
如果我们只想包含一个简单的静态 HTML 文档,我们可以在 public 目录中执行此操作。换句话说,文件 blog/public/foo.html 在 WEBrick 下可用——通过执行启动blog/script/server—在 URL /foo.html 上。
当然,我们有兴趣做一些比提供静态 HTML 文档更有趣的事情。我们可以通过创建一个控制器类,然后在该类中定义一个方法来生成基本的“Hello, world”消息来做到这一点。诚然,这违反了 Rails 试图强制执行的 MVC 分离,但作为对事物如何运作的简单指示,这似乎是很好的下一步。
要生成名为 MyBlog 的新控制器类,我们进入 blog 目录并键入
ruby script/generate controller MyBlog
每次我们想在 Rails 应用程序中创建一个新组件时,我们都会调用script/generate来创建一个骨架。然后我们可以修改该骨架以满足我们的特定需求。与往常一样,Rails 会在创建文件和目录时告诉我们它在做什么
exists app/controllers/ exists app/helpers/ create app/views/my_blog exists test/functional/ create app/controllers/my_blog_controller.rb create test/functional/my_blog_controller_test.rb create app/helpers/my_blog_helper.rb
另请注意,我们的控制器类名 MyBlog 如何转换为各种 Ruby 文件名,例如 app/views/my_blog 和 app/helpers/my_blog_helper.rb。创建更多控制器类,您应该看到所有名称(如 FooBar)都在名称如 foo_bar 的文件中实现。这是 Rails 保持名称一致的约定的一部分。这种一致性使 Rails 能够近乎神奇地处理许多项目,尤其是——我们将在下个月看到——当涉及到数据库时。
我们感兴趣的控制器是 my_blog_controller.rb。如果您在编辑器中打开它,您应该看到它由两行组成
class MyBlogController < ApplicationController end
换句话说,此文件定义了 MyBlogController,这是一个从 ApplicationController 类继承的类。就目前而言,定义是空的,这意味着我们既没有覆盖父类中的任何方法,也没有编写任何我们自己的新方法。让我们改变这一点,使用内置的 render_text 方法来生成一些输出
class MyBlogController < ApplicationController def hello_world render_text "Hello, world" end end
添加此方法定义后,我们可以通过转到 http://192.168.2.3:3000/MyBlog/hello_world 来查看其结果。
请注意 URL 是如何更改的:公共目录中的静态项目(例如我们的文件 foo.html)位于根 URL / 正下方。相比之下,我们的方法 hello_world 通过名称在我们生成的控制器类下访问。另请注意,我们无需重新启动 Rails 即可创建和测试此定义。一旦创建或更改方法,它就会立即被注意到并集成到当前的 Rails 系统中。
如果我们为控制器类定义一个 index 方法,我们可以指示默认情况下应显示什么
class MyBlogController < ApplicationController def hello_world render_text "Hello, world" end def index render_text "I am the index!" end end
当然,能够生成静态文本并没有那么令人兴奋。因此,让我们修改我们的 index 方法,使其使用 Ruby 的内置 Time 对象来显示当前日期和时间
def index render_text "The time is now " + Time.now.to_s + "\n" end
瞧!一旦我们将此修改保存到磁盘,默认 URL (http://192.168.2.3:3000/MyBlog/,在我的计算机上) 就会显示发出请求时的日期和时间,而不是永不更改的“Hello, world”消息。
让我们通过再次将控制器与其视图分离来结束对 Rails 的介绍。换句话说,我们希望控制器处理逻辑,而视图处理 HTML 输出。Rails 再次允许我们通过利用其命名约定轻松地做到这一点。例如,让我们再次修改我们的 index 方法,这次删除其整个主体
def index end
乍一看这似乎很奇怪。它告诉 Rails MyBlog 控制器类有一个 index 方法。但它不生成任何输出。如果您尝试检索与之前相同的 URL,Rails 会生成一条错误消息,指示它找不到合适的模板。
由于模板是一个视图,我们可以在应用程序的 blog/app/views 目录中定义它。并且由于我们正在为 MyBlog 类定义 index 视图,因此我们修改 views 的 my_blog 子目录中的 index.rhtml 文件。请注意,Rails 在处理目录时如何将 ThisName 转换为 this_name。这样做可以避免用户在 URL 中考虑大小写,同时与传统的 Ruby 类命名约定保持一致。
.rhtml 文件是您之前可能见过的同类模板的 Ruby 版本。它的行为类似于 ASP 和 JSP 语法,其中 <% %> 块包含代码,<%= %> 块包含应插入到模板中的表达式。但是,没有什么可以阻止我们创建一个实际上是静态的 .rhtml 模板
<html> <head> <title> Hello, again! </title> </head> <body> <p>Hello, again!</p> </body> </html>
考虑一下如果您现在尝试在浏览器中加载 MyBlog 会发生什么。控制器类 MyBlog 被传递请求。由于没有明确命名方法,因此调用 index 方法。并且由于 index 不产生任何输出,因此 my_blog/index.rhtml 模板将返回给用户。
最后,让我们利用模板的动态属性在控制器中设置一个值,并将其传递给模板。我们修改我们的 index 方法以读取
def index @now = Time.now.to_s end
请注意我们如何在变量 @now 的开头使用了 @ 字符。我发现这起初有点令人困惑,因为 @ 通常用作 Ruby 中实例变量的前缀。但是过一段时间后,它很快就会变得相当自然和合乎逻辑。
最后,我们修改我们的模板,使其包含 @now 中包含的字符串值
<html> <head> <title> Hello, world! </title> </head> <body> <p>Hello, world!</p> <p>It is now <%= @now %>.</p> </body> </html>
再次,即使不重新启动 Ruby,您也可以检索该页面。您应该看到服务器上保留的日期和时间,每次刷新页面时都会更新。
毫无疑问,Ruby on Rails 是过去几年中出现的最受关注的 Web 技术之一。本月,我们了解了创建新的 Rails 应用程序、创建控制器和视图以及使用命名约定和相对标准的模板语法的组合来集成它们是多么的简单明了。但是,我们没有讨论视图,特别是那些与关系数据库关联的视图。下个月,我们将完全做到这一点,将 Rails 连接到 PostgreSQL 数据库。我相信这样做将开始展示人们为什么对 Rails 如此兴奋,以及为什么它可能是许多 Web 开发人员学习的好工具。
本文资源: /article/8457。