构建 Rails 模型之间的关系
贡献者:Brian Leonard,维护者:Gail Chappell
2007 年 12 月 [修订号:V6.0-3]
翻译:Dave(NetBeans 中文社区成员)
本教程介绍如何在 NetBeans Ruby on Rails 项目中构建模型之间的关系(一对一和多对一)。
|
目录
|
|
 |
教程需求
学习本教程需要以下技术和资源:
创建样例数据库
注意:本教程使用 MySQL 数据库服务器。您可以参考
安装和配置 Ruby 支持一文以获取有关如何在 Ruby 应用程序中使用 MySQL 数据库服务器的信息。该文档同样介绍了如何使用 JavaDB 数据库服务器作为替代。
- 打开一个命令行窗口。
- 如果 MySQL 数据库服务器尚未被启动,请先将其启动。
- 键入如下命令来创建开发数据库,并按“Enter”键。
mysqladmin -u root -p create rubyweblog_development
注意:如果 root 用户不要求密码,请省略 -p 参数。
-
在 IDE 中打开 rubyweblog 项目。
注意:如果是初次打开或者创建 Ruby 项目,IDE 会检查您是否有除了绑定的 JRuby 软件之外其他的 Ruby 安装。如果有,IDE 会显示一个对话框,询问您选择使用哪个软件。若您想要使用绑定的 JRuby 解释器,选择 JRuby;或者您喜欢使用您自己的 Ruby 安装,那就选择您自己的安装。更多信息,请参考《安装和配置 Ruby》教程中的配置 IDE 使用您自己的 Ruby 安装一节。
-
如果您的数据库要求密码,请编缉 database.yml 文件,并在开发配置部分中提供密码。保存该文件。
要快速访问 database.yml 文件,按 Alt+Shift+O(在 Mac 系统中按 Ctrl+Shift+O),在“文件名”文本框中键入 database.yml,然后按“Enter”键。
-
右键点击 rubyweblog 节点,选择“迁移数据库”>“到当前版本”。
该操作会更新数据库以加入 posts 表并添加 body 字段。 迁移完成时会在“输出”窗口显示。
- 运行应用程序并发表一篇新文章。
创建评论模型
本教程通过增加允许读者给 blog 文章添加评论的功能扩充 rubyweblog 项目。首先要创建评论模型来存储读者评论实例。而此项目中已经有了存储 blog 文章实例的文章模型。
-
在“项目”窗口中,展开“rubyweblog”节点,右键点击“Models”节点,然后选择“Generate”。
-
在“Arguments”字段中键入 Comment post_id:integer created_at:datetime comment:text,然后点击“OK”。
“Rails Generator”会创建一个名为“Comment”的模型。该模型包含如下文件:
- app/models/comment.rb 存有评论模型方法的文件。此文件已在编辑区中打开。
- test/unit/comment_test.rb 用于检测模型的单元测试。
- test/fixtures/comments.yml 用于填充模型的测试套件
- db/migrate/migrate/003_create_comments.rb 更改数据库结构的迁移文件。 该文件的版本为003,这是因为项目已经有了两个迁移文件:
001_create_posts.rb 和 002_add_body.rb,他们用于创建和修改 posts 表。
迁移数据库
接下来要处理的文件就是迁移文件 003_create_comments.rb 了。
-
在“输出”窗口中,点击 003_create_comments.rb 文件的链接。
文件打开后会显示 self.up 方法(创建 comments 表)和 self.down 方法(删除 comments 表),如下列代码示例所示:
| 代码示例 1:comments 表的迁移代码 |
class CreateComments < ActiveRecord::Migration def self.up create_table :comments do |t| t.column :post_id, :integer t.column :created_at, :datetime t.column :comment, :text end end
def self.down drop_table :comments end end
|
此段迁移代码会创建一张含有 4 个字段 comments 表:id,整数;post_id,整数;created_at,存储日期时间;comment,文本描述。
-
右键点击 rubyweblog 节点,选择“迁移数据库”>“到当前版本”。
该操作会更新数据库以加入 comments 表。 迁移完成时会在“输出”窗口显示。
定义评论模型和文章模型之间的关系
应用程序目前有两个模型:文章模型发表一篇新的 blog 文章,而评论模型则向一篇 blog 文章添加一条评论。现在给两个模型之间定义关系, 使得一条评论关联一篇文章,而一篇文章可以包含多条评论。
- 展开“Models”节点,打开
post.rb。
-
在 post.rb 中添加如下 has_many 关联:
代码示例 2:post.rb 中的 has_many 关联 |
class Post < ActiveRecord::Base validates_presence_of :title, :body has_many :comments end
|
has_many 方法表明文章可以有 0 个、1 个或者多个评论记录与之关联。
小贴士: 键入触发器 hm后按 Tab 键,可以扩展成代码模板 has_many :objects。
-
打开“Models”> comment.rb,然后添加 belongs_to 关联:
代码示例 3:comment.rb 中的 belongs_to 关联 |
class Comment < ActiveRecord::Base belongs_to :post end
|
belongs_to 方法表明一条评论只能和一篇文章相关联。ActiveRecord 默认使用 post_id 来将一条评论和有相应 post.id 的文章进行关联。
小贴士:bt 触发器能扩展成 belongs_to :object。
修改控制器脚手架
接下来处理控制器,blog_controller.rb,它能生成用于在 blog 文章中创建、读取、更新和删除条目的脚手架或者基本接口。
-
展开“Controllers”节点,打开 blog_controller.rb。
控制器拥有所有的脚手架动作,包括 index、list、show、new、create、edit、update 和 destroy。
-
如下面的代码示例所示,修改 show 动作,将 post_id 保存到 flash 中:
代码示例 4:show 动作 |
def show @post = Post.find(params[:id]) flash[:post_id] = @post.id end
|
此段代码查找与请求中所传的参数 id 相关联的文章。然后把 id 存放到 flash 中以备后用。flash 类似于 HTTP 会话,但可以跨越单个请求。当在 flash 中放入一个物品时,该物品对下个请求可用,但然后就消失了(因此使用术语“flash”称之)。
-
滚动至 blog_controller.rb 文件的结尾处,然后在最后的 end 语句前添加如下 post_comment 动作:
代码示例 5:post_comment 动作 |
def post_comment @comment = Comment.new( "post_id" => flash[:post_id], "created_at" => Time.now, "comment" => params[:comment]['comment'] ) if @comment.save flash[:notice] = 'Comment was successfully added.' redirect_to :action => 'show', :id => flash[:post_id] end end
|
当用户点击“Post”按钮提交评论时就会调用 post_comment 动作。此段代码的第一段从 flash 中获取 post_id(1, 2, ...),并使用该 id 查找与之相关联的 blog 文章。紧接着代码会创建一个新的评论对象来关联该 post_id,组成部分还包括创建时间和实际评论。Rails 框架把从页面提交的参数作为散列来传递(params[:comment]),通过该散列码能够取出评论参数(params[:comment]['comment'])。
由于评论(Comment)是一个 ActiveRecord 类,故调用其 save 方法可以将评论记录保存到数据库中。接着把成功保存记录的消息放到 flash 中。代码然后调用 show 动作,载入 show.rhtml 页面。该页面将重新载入文章和与它相关的所有评论,包括新添加的那条。
修改视图以添加评论
编缉 show.rhtml 文件,显示单独的 blog 条目。
- 展开“Views”> blog,然后打开
show.rhtml。
-
在 show.rhtml 文件末尾添加下列代码:
代码示例 6:show.rhtml 所需代码 |
<hr> <h4>Comments</h4>
<% form_tag :action => 'post_comment' do %> <p><label for="comment_comment">Comment</label><br/>
<%= text_area 'comment', 'comment' %></p> <%= submit_tag "Post" %> <%end %>
|
此段代码产生一个表单,包括一个用于编写评论的文本输入区,和一个标识为 Post 的提交按钮,如图 1 所示。表单提交时会调用 post_comment 动作。
- 保存文件,然后运行应用程序。
-
点击“Permalink”查看 blog 条目的详细信息。 试着在文本区添加一条评论,但是请留意当点击“Post”按钮时 blog 还不能显示评论。
如果您的提交成功了,您可以看到视图顶部会有一条消息,如下图所示。后面几个步骤,我们将添加代码来收集并显示这些评论。
图 1:没有显示评论的评论模型视图

显示评论
blog 目前还不能显示读者添加的评论,所以现在来解决这个问题。
-
在 blog_controller.rb 中查找 show 动作,然后插入下面的 post_comments 实例变量来收集评论。
代码示例 7:blog_controller.rb 所需代码 |
def show @post = Post.find(params[:id]) @post_comments = @post.comments.collect flash[:post_id] = @post.id end
|
由于给文章模型添加了 has_many :comments 关系,可以通过调用 @post.comments 来访问一篇文章的所有评论。
-
修改 show.rhtml,将下面 <ul> 标签的内容复制粘贴到 <h4>Comments</h4> 行下面:
代码示例 8:show.rhtml 所需代码 |
<ul>
<% @post_comments.each do |comment| %> <li><%= h comment.comment %><br> <div style="color: #999; font-size: 8pt"> Posted on <%= comment.created_at.strftime("%B %d, %Y at %I:%M %p") %> </div>
</li> <% end %> </ul>
|
此段代码设定评论显示风格,以符合列表显示评论,同时加入评论发表的日期和时间。
-
选择“文件”>“全部保存”,然后刷新浏览器。
现在评论就以符号列表的形式显示在 blog 中了,如下图所示。
图 2:显示评论的评论模型视图

更多内容