Rails3教程系列之五:Rails3入门(5)

1. 添加第二个模型

在前面的教程中,我们已经学会的使用脚手架快速搭建一个简单的应用,毕竟脚手架不能做任何事情,现在我们需要在应用中添加第二个模型了。

模型在rails中使用单数形式,而其相关的数据库将使用复数名称。

那么对于一个博客来说,评论总是少不了的,我们现在就要创建一个 Comment 模型。对于大多数的 rails 程序员来说,一般都是通过rails的生成器来生成模型,在这里我们也一样:

$ rails g model comment commenter:string body:text post:references

该命令将创建4个文件:

  • app/models/comment.rb – 模型
  • db/migrate/20101128142329_create_comments.rb – 迁移文件
  • test/unit/comment_test.rb and test/fixtures/comments.yml – 测试文件.
首先,我们看一下 comment.rb
Ruby代码 复制代码 收藏代码
  1. class Comment < ActiveRecord::Base 
  2.   belongs_to :post 
  3. end 
class Comment < ActiveRecord::Base
  belongs_to :post
end
初看之下,你可能会觉得它与post模型很相识,不同之处在于它多了一行 belongs_to 声明,而这将会建立它与post模型之间的关联, 那么在后面的教程中我们将详细学习。

同时,Rails还生成了迁移文件来创建相应的表:
Ruby代码 复制代码 收藏代码
  1. class CreateComments < ActiveRecord::Migration 
  2.   def self.up 
  3.     create_table :comments do |t| 
  4.       t.string :commenter 
  5.       t.text :body 
  6.       t.references :post 
  7.   
  8.       t.timestamps 
  9.     end 
  10.   end 
  11.   
  12.   def self.down 
  13.     drop_table :comments 
  14.   end 
  15. end 
class CreateComments < ActiveRecord::Migration
  def self.up
    create_table :comments do |t|
      t.string :commenter
      t.text :body
      t.references :post
 
      t.timestamps
    end
  end
 
  def self.down
    drop_table :comments
  end
end
与之前的rails版本不同,这里多了一个 t.references 定义。t.references :post 将建立一个posts表的外键 post_id, 值得注意的是这里的 :post 指的模型而不是表,这点一定要搞清楚。
现在运行迁移操作把:

$ rake db:migrate

2. 关联模型
Active Record的关联让你很容易的声明模型之间的关系。对于Posts和Comments, 很明显是一对多的关系。
前面rails已经为我们声明了 belongs_to 关系,现在我们需要再声明一个 has_many 关系, 打开 post.rb 然后添加下面一行:
Ruby代码 复制代码 收藏代码
  1. class Post < ActiveRecord::Base 
  2.   validates :name:presence => true 
  3.   validates :title, :presence => true
  4.                     :length => { :minimum => 5 } 
  5.   
  6.   <strong>has_many :comments</strong> 
  7. end 
class Post < ActiveRecord::Base
  validates :name,  :presence => true
  validates :title, :presence => true,
                    :length => { :minimum => 5 }
 
  has_many :comments
end
现在双方都已经建立起一系列的关系,打个比方,假如你有一个实例变量 @post 包含一条 post,那么你可以使用 @post.comments 来检索所有该 post 中的 comment。

3. 为comments添加路由
和home控制器一样,我们需要添加一条路由,这样rails可以知道哪里可以看到评论。再次打开 routes.rb 你可以看到上次手脚架自动给posts添加的路由条目,我们编辑下该条目:
Ruby代码 复制代码 收藏代码
  1. resources :posts do 
  2.   resources :comments 
  3. end 
resources :posts do
  resources :comments
end
这将使 comments 资源作为 posts 资源的嵌套资源。而这也反映出 post 与 comment 之间的关系。

4. 生成控制器
模型有了,现在你需要创建comments控制器了,同样我们使用生成器来创建该控制器:

$ rails g controller comments

与任何博客一样,我们的读者将在他们阅读文章后直接添加评论,一旦完成评论的添加,他们将跳转到post的show页面,所以,我们的CommnetsController仅需提供创建以及删除垃圾评论的方法即可。

首先,我们修改下post的show.html.erb模板使之可以创建与显示评论:
Html代码 复制代码 收藏代码
  1. <p class="notice"><%= notice %></p> 
  2.   
  3. <p> 
  4.   <b>Name:</b> 
  5.   <%= @post.name %> 
  6. </p> 
  7.   
  8. <p> 
  9.   <b>Title:</b> 
  10.   <%= @post.title %> 
  11. </p> 
  12.   
  13. <p> 
  14.   <b>Content:</b> 
  15.   <%= @post.content %> 
  16. </p> 
  17.   
  18. <h2>Add a comment:</h2> 
  19. <%= form_for([@post, @post.comments.build]) do |f| %> 
  20.   <div class="field"> 
  21.     <%= f.label :commenter %><br /> 
  22.     <%= f.text_field :commenter %> 
  23.   </div> 
  24.   <div class="field"> 
  25.     <%= f.label :body %><br /> 
  26.     <%= f.text_area :body %> 
  27.   </div> 
  28.   <div class="actions"> 
  29.     <%= f.submit %> 
  30.   </div> 
  31. <% end %> 
  32.   
  33. <%= link_to 'Edit Post', edit_post_path(@post) %>
  34. <%= link_to 'Back to Posts', posts_path %>
<p class="notice"><%= notice %></p>
 
<p>
  <b>Name:</b>
  <%= @post.name %>
</p>
 
<p>
  <b>Title:</b>
  <%= @post.title %>
</p>
 
<p>
  <b>Content:</b>
  <%= @post.content %>
</p>
 
<h2>Add a comment:</h2>
<%= form_for([@post, @post.comments.build]) do |f| %>
  <div class="field">
    <%= f.label :commenter %><br />
    <%= f.text_field :commenter %>
  </div>
  <div class="field">
    <%= f.label :body %><br />
    <%= f.text_area :body %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>
 
<%= link_to 'Edit Post', edit_post_path(@post) %> |
<%= link_to 'Back to Posts', posts_path %> |
这将在post的show页面中显示一个comment表单来创建评论,而这将调用CommentsController中的create方法,如下:
Ruby代码 复制代码 收藏代码
  1. class CommentsController < ApplicationController 
  2.   def create 
  3.     @post = Post.find(params[:post_id]) 
  4.     @comment = @post.comments.create(params[:comment]) 
  5.     redirect_to post_path(@post
  6.   end 
  7. end 
class CommentsController < ApplicationController
  def create
    @post = Post.find(params[:post_id])
    @comment = @post.comments.create(params[:comment])
    redirect_to post_path(@post)
  end
end
你可能会发现这里要比之前的posts控制器中稍微复杂一些,这就是你之前设定嵌套的片效应。每一个评论的请求需要追踪该评论所附加的Post,所以find首先会找出该Post对象。

接下来,代码调用了关联中存在的方法,我们在这里使用create方法来创建并保存该条评论,这将自动关联到对应的post记录。

一旦我们完成了评论的保存,我们就要使用 post_path @post 把用户跳转到原来显示该post的show页面。正如我们所看到的,它调用了PostsController中的show方法来渲染show.html.erb 模板。这里我们需要显示所有关于该Post的评论,所以让我们更改下 show.html.erb 页面:
Html代码 复制代码 收藏代码
  1. <p class="notice"><%= notice %></p> 
  2.   
  3. <p> 
  4.   <b>Name:</b> 
  5.   <%= @post.name %> 
  6. </p> 
  7.   
  8. <p> 
  9.   <b>Title:</b> 
  10.   <%= @post.title %> 
  11. </p> 
  12.   
  13. <p> 
  14.   <b>Content:</b> 
  15.   <%= @post.content %> 
  16. </p> 
  17.   
  18. <h2>Comments</h2> 
  19. <% @post.comments.each do |comment| %> 
  20.   <p> 
  21.     <b>Commenter:</b> 
  22.     <%= comment.commenter %> 
  23.   </p> 
  24.   
  25.   <p> 
  26.     <b>Comment:</b> 
  27.     <%= comment.body %> 
  28.   </p> 
  29. <% end %> 
  30.   
  31. <h2>Add a comment:</h2> 
  32. <%= form_for([@post, @post.comments.build]) do |f| %> 
  33.   <div class="field"> 
  34.     <%= f.label :commenter %><br /> 
  35.     <%= f.text_field :commenter %> 
  36.   </div> 
  37.   <div class="field"> 
  38.     <%= f.label :body %><br /> 
  39.     <%= f.text_area :body %> 
  40.   </div> 
  41.   <div class="actions"> 
  42.     <%= f.submit %> 
  43.   </div> 
  44. <% end %> 
  45.   
  46. <br /> 
  47.   
  48. <%= link_to 'Edit Post', edit_post_path(@post) %>
  49. <%= link_to 'Back to Posts', posts_path %>
<p class="notice"><%= notice %></p>
 
<p>
  <b>Name:</b>
  <%= @post.name %>
</p>
 
<p>
  <b>Title:</b>
  <%= @post.title %>
</p>
 
<p>
  <b>Content:</b>
  <%= @post.content %>
</p>
 
<h2>Comments</h2>
<% @post.comments.each do |comment| %>
  <p>
    <b>Commenter:</b>
    <%= comment.commenter %>
  </p>
 
  <p>
    <b>Comment:</b>
    <%= comment.body %>
  </p>
<% end %>
 
<h2>Add a comment:</h2>
<%= form_for([@post, @post.comments.build]) do |f| %>
  <div class="field">
    <%= f.label :commenter %><br />
    <%= f.text_field :commenter %>
  </div>
  <div class="field">
    <%= f.label :body %><br />
    <%= f.text_area :body %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>
 
<br />
 
<%= link_to 'Edit Post', edit_post_path(@post) %> |
<%= link_to 'Back to Posts', posts_path %> |
现在你可以在你的博客中添加post和评论了,并且把它们显示在正确的地方。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值