在 10 分钟内创建 Ruby 博客
撰稿人:Brian Leonard,维护人:Chris Kutler
2008 年 11 月 [修订版本号:V6.5-1]
在本教程中,我将利用 NetBeans IDE 对 Ruby 的支持创建并运行一个简单的数据库 Web 应用程序。通过完成本教程中的步骤,您将学习如何执行以下任务:
- 使用 Rake 任务和迁移文件创建和更新数据库表
- 使用 Scaffold 生成器生成基本的创建、读取、更新和删除(CRUD)数据库 Web 应用程序
- 编译视图以完善 Web 页
如果您刚接触 NetBeans IDE,则在学习此教程之前可能需要先完成 NetBeans IDE Ruby 快速入门教程,以便可以更熟悉 UI。
目录

要学完本教程,您需要具备以下软件和资源。
*JRuby 软件与 Rails 2.1.1 不兼容。您必须使用版本 2.1.0(附带于内置的 JRuby 软件中)或 Rails 版本 2.1.2(最低版本)。
创建 Ruby on Rails 项目
首先,创建一个 Ruby on Rails 项目。缺省情况下,IDE 将在目录结构中创建符合应用程序的 Ruby on Rails 项目约定的项目。
-
在 NetBeans IDE 中,选择“文件”>“新建项目”。
-
从“类别”列表中选择 "Ruby",从“项目”列表中选择“Ruby on Rails 应用程序”,如下图所示。

- 单击“下一步”,为项目命名并指定位置。
-
在“项目名称”文本框中键入 rubyWeblog,如下图所示。
接受此页面上的所有其他缺省设置。

-
如果满足以下条件,请直接跳到步骤 8。
- 您正使用缺省的
root 用户名。
- 访问
root 不需要口令。
- 您正使用 MySQL 数据库服务器。
IDE 缺省假定这些条件。
-
单击“下一步”可配置数据库。
-
选择“直接指定数据库信息”选项,选择“数据库适配器”,键入用户名和密码。将“数据库名称”设置保留为 rubyweblog_development。
-
单击“完成”以创建一个新项目。
IDE 将创建一个与您项目同名的项目目录,并在编辑区域打开 database.yml 文件。
-
验证开发部分的适配器、数据库、用户名和口令设置对于开发和测试配置是否正确,然后单击 database.yml 标签中的小 x 按钮以关闭文件。

创建 Scaffold
此 Weblog 应用程序是基于 Post 模型创建的,其中了存储博客帖子实例。现在,我们将使用 Rails Scaffold 生成器创建模型及其控制器,以及索引(列表)、显示、新建和编辑视图。
生成器还将创建一个用于创建模型的数据库表的迁移文件,并为编写模型测试创建单元测试和固定桩。
-
在“项目”窗口中,右键单击 rubyweblog 项目节点,然后从弹出式菜单中选择“生成”。
-
在“Rails 生成器”对话框中,从“生成”下拉列表中选择 "Scaffold",如下图所示。

-
在“模型名称”文本框中键入 Post。
-
在“属性对”文本框中键入 title:string 并单击“确定”。
“输出”窗口将列出 Scaffold 生成器创建和更新的文件列表。
创建数据库
在本节中,我们将使用 Rake 任务创建 rubyWeblog_development 数据库。然后,可以使用迁移文件将 posts 表添加到数据库中。
-
在“项目”窗口中,右键单击 rubyweblog 项目节点,然后从弹出式菜单中选择“运行/调试 Rake 任务”。
-
在“过滤器”文本框中键入 db,以将任务列表的范围缩小至仅显示 db 任务,如下图所示。

-
从“匹配任务”列表中选择 db:create 并单击“完成”。
Rake 将针对 database.yml 文件中定义的开发配置创建数据库。
注意:如果在“输出”窗口中看到错误消息,请验证 database.yml 文件的开发部分中的用户名和口令正确无误。同样,验证数据库服务器正在运行。
-
在“项目”窗口中,依次展开“数据库迁移”和 "migrate" 节点。
-
双击迁移类的节点,该节点的名称将以日期和时间开头并以 create_posts.rb 结束。
该文件随即打开,以显示 self.up 方法(用于创建名为 "posts" 的表)和 self.down 方法(用于销毁 posts 表),如以下代码样例所示。
class CreatePosts < ActiveRecord::Migration
def self.up
create_table :posts do |t|
t.string :title
t.timestamps
end
end
def self.down
drop_table :posts
end
end
请注意,缺省情况下,create_table 方法将添加一个 id 列,timestamps 方法将在数据库表中添加 created_at 和 updated_at 列。
-
在“项目”窗口中,右键单击 rubyweblog 节点并选择“迁移数据库”>“至当前版本”。
此操作将在数据库中添加 posts 表。“输出”窗口将指示迁移完成,如下图所示。

运行应用程序
接下来,测试应用程序。
-
在“项目”窗口中,展开“配置”节点,双击 "routes.rb" 以便在编辑器中将其打开。
-
找到下面这行代码:
# map.root :controller => "welcome"
-
取消注释该行并将控制器更改为 "posts",如下所示。
map.root :controller => "posts"
-
在“项目”窗口中,展开“公共”节点,右键单击 index.html,然后从弹出菜单中选择“删除”。
index.html 页面将显示缺省的欢迎页面,而这并不是您想要的。通过删除 index.html,Rails 将在 routes.rb 中寻找需要显示的页面。
-
从主菜单中选择“文件”>“保存所有”。
-
右键单击 rubyweblog 节点,然后从弹出式菜单中选择“运行”。
此操作将启动服务器并在浏览器中显示以下页面。

-
单击“新建”链接显示应用程序的第二个页面,如下图所示。

-
输入一个标题,然后单击“创建”。
下图就是创建博客日志的一个样例。

-
单击“返回”链接可返回帖子列表。
添加另一个表列
您可以在此处向 posts 表中添加一个 body 列,以存放每个博客条目的文本。
-
右键单击“数据库迁移”节点,并从弹出菜单中选择“生成”。
这将打开“Rails 生成器”对话框,它已经在“生成”下拉列表中选择了迁移。
-
在“参数”文本框中输入 AddBodyToPost body:text,如下图所示。

-
单击“确定”。
IDE 将创建一个受版本控制的迁移脚本。该脚本的名称以日期和时间开头,并以 add_body_to_post.rb 结束。该文件随即打开,以显示 self.up 方法(用于添加 body 列)和 self.down 方法(用于删除列),如以下代码样例所示。注意生成代码是如何从第一个参数 AddBodyToPost中提取出表名的。
class AddBodyToPost < ActiveRecord::Migration
def self.up
add_column :posts, :body, :text
end
def self.down
remove_column :posts, :body
end
end
-
右键单击 "RubyWebLog" 节点,从弹出菜单中选择“迁移数据库”>“至当前版本”。
或者,在源文件中单击鼠标右键并从弹出菜单中选择“运行”。
-
在“项目”窗口中,分别展开“视图”和 "posts",双击 edit.html.erb 以便在编辑区域将其打开。
-
将以下代码样例中粗体显示的语句添加到 edit.html.erb 文件。
或者,将光标放在 Title 字段的 <p> 标记前面,再将光标拖动到段落结束 </p> 标记后。然后,按 Ctrl+Shift+向下方向键组合键以复制行。编辑复制的语句,如以下代码所示。
<h1>Editing post</h1>
<% form_for(@post) do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :title %><br />
<%= f.text_field :title %>
</p>
<p>
<%= f.label :body %><br />
<%= f.text_area :body %>
</p>
<p>
<%= f.submit "Update" %>
</p>
<% end %>
<%= link_to 'Show', @post %> |
<%= link_to 'Back', posts_path %>
-
双击 new.html.erb,以便编译区域打开该文件。
-
将以下代码样例中粗体显示的语句添加到 new.html.erb 文件。或者,使用 Ctrl+Shift+向下方向键组合键来复制 Title 段落并编辑复制的语句,如以下代码所示。
<h1>New post</h1>
<% form_for(@post) do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :title %><br />
<%= f.text_field :title %>
</p>
<p>
<%= f.label :body %><br />
<%= f.text_area :body %>
</p>
<p>
<%= f.submit "Create" %>
</p>
<% end %>
<%= link_to 'Back', posts_path %>
-
双击 show.html.erb,以便编辑区域打开该文件。
-
将以下代码样例中粗体显示的语句添加到 show.html.erb 文件。或者,使用 Ctrl+Shift+向下方向键组合键按照步骤 6 所述复制 Title 段落,将 Title: 更改为 Body:,并将 @post.title 更改为 @post.body。
<p>
<b>Title:</b>
<%=h @post.title %>
</p>
<p>
<b>Body:</b>
<%=h @post.body %>
</p>
<%= link_to 'Edit', edit_post_path(@post) %> |
<%= link_to 'Back', posts_path %>
-
从主菜单中选择“文件”>“保存所有”。
-
返回浏览器并单击“新建帖子”链接查看新 body 栏,如下图所示。

-
创建更多的博客条目。
完成之后,单击“返回”可返回“帖子列表”页。
验证输入
当前,用户可以向博客中添加空帖子。您可以在此处修改应用程序以阻止空白帖子。首先,准备测试数据库并编写单元测试,以验证除非帖子具有标题和正文,否则用户将无法创建。接下来,向 Post 类中添加代码,要求用户为标题和正文字段提供值。最后,运行单元测试,以验证修改工作如期进行,然后运行应用程序。
- 在“项目”窗口中,右键单击 rubyweblog 节点,然后从弹出式菜单中选择“运行/调试 Rake 任务”。
- 在“参数”文本框中键入 RAILS_ENV=test。
- 找到并双击 db:create 条目,以运行任务,从而创建 rubyweblog_test 数据库。
- 再次右键单击 rubyweblog 节点,然后从弹出式菜单中选择“运行/调试 Rake 任务”。
-
找到并双击 db:test:prepare 条目。
您现在具有一个包含 Post 表的测试数据库。
-
在“项目”窗口中,展开“单元测试”并双击 post_test.rb,以便在编辑区域中将其打开。
-
将该文件的内容替换为以下代码。
require 'test_helper'
class PostTest < ActiveSupport::TestCase
def test_invalid_with_empty_attributes
post = Post.new
# An empty Post model should be invalid
assert !post.valid?
# The title field should have validation errors
assert post.errors.invalid?(:title)
# The body field should have validation errors
assert post.errors.invalid?(:body)
end
end
-
右键单击 rubyweblog 项目节点,然后从弹出式菜单中选择“测试”。
IDE 将运行项目的所有单元测试并在“Ruby 测试结果”窗口中显示输出,如下图所示。由于应用程序允许空帖子,因此 Post 模型的单元测试将出现故障。接下来,您应修改应用程序,以要求为“文本”和“正文”列提供值。

-
在“项目”窗口中,展开“模型”节点并双击 post.rb,以便编辑器中将其打开。
-
在类定义中打开一个新行,键入 vp 并按 Tab 键。
IDE 将 vp 触发器替换为以下参数化的代码模板。
validates_presence_of :attribute
-
键入 title, :body,然后按 Enter 键。代码应与以下语句类似。
validates_presence_of :title, :body
-
要重试单元测试以查看更改是否会创建所需效果,请右键单击 rubyweblog 节点并从弹出式菜单中选择“测试”。
PostTest 将通过,但某些 PostController 测试会由于您对 Posts 模型所做的验证更改而失败。您应在接下来的两个步骤中纠正此问题。
-
在“Ruby 测试结果”窗口中,双击 test_should_create_post 节点,以便编辑区域中打开该测试。
-
将 post :create, :post => {} 替换为以下代码,该代码为标题和正文提供值。
post :create, :post => { :title => "Nene",
:body => "Nenes are Hawaiian Geese" }
-
滚动到 test_should_update_post 方法并更改 put 调用,以便同时在标题和正文中通过,如以下代码所示。
put :update, :id => posts(:one).id,
:post => {:title => "Nene", :body => "Are rare birds." }
-
要验证测试现在是否已通过,请在编辑区域中单击鼠标右键并从弹出式菜单中选择“测试文件”。
IDE 将运行 PostsControllerTest 类中的测试,并在“Ruby 测试结果”窗口中显示输出。
-
返回浏览器,单击“新建帖子”,然后单击“创建”。
应用程序将立即报告标题和正文不能为空,如下图所示。

使列表看起来更像是一个博客
现在,我们将编辑 index.html 视图,使列表看起来更像是一个博客,如下图所示。

-
在“项目”窗口中,分别展开“视图”节点和 "posts",双击 edit.html.erb 以便编辑区域将其打开。
此视图显示了博客条目列表。
-
删除 <h1> 和 <table> 元素,并将它们替换为下面以粗体显示的代码。
<h1>The Ruby Blog</h1>
<% for post in @posts %>
<h2><%= post.title %></h2>
<p><%= post.body %></p>
<small>
<%= link_to "permalink",
:action => "show",
:id => post %>
</small>
<hr>
<% end %>
<br />
<%= link_to 'New post', new_post_path %>
对于 post 操作的各实例,此代码将生成标题、正文和 Permalink。
-
保存更改并运行应用程序,查看 Post 模型的新界面。
-
要将最新条目显示在博客最前面,请编辑您刚才添加的代码,添加一个 .reverse 方法反转排序顺序,如下所示。
<% for post in @posts.reverse %>
-
保存文件并刷新您的浏览器,查看反序排序的列表。
应用所学知识
使用您在本练习中学到的技巧创建一个任务列表 Web 项目。使用 Scaffold 生成器围绕 Task 模型构建一个含 title:string 和 description:text 字段的 Scaffold。使用 Rake 创建数据库,然后使用“数据库迁移”创建表。不要忘记编辑 route.rb 文件来映射 root,但要记住删除 index.html 文件。
后续步骤
>> 更多 NetBeans Ruby 文档