Rails 增加一个模型(model)

 

 

之前我们已经看到用脚手架运行的model程序。现在是时候第二个model了。

第二个model用来处理post的评论。


7.1 新建一个模型

Rails模型使用一个单一的名称,相应的数据库使用复数名称

像模型来处理comments表,模型的名字所comment。即使你不想使用

脚手架来产生全部代码。很多程序还是用generators来产生控制器和模型。

新建一个模型可以像下面一样:运行命令。

  1. $ rails generate model Comment commenter:string body:text post:references  

这个命令将会生成下面几个文件

  • app/models/comment.rb – 模型文件
  • db/migrate/20100207235629_create_comments.rb – DB整合文件
  • test/unit/comment_test.rb and test/fixtures/comments.yml –测试配置文件

首先我们看下模型文件

  1. class Comment < ActiveRecord::Base  
  2.   belongs_to :post  
  3. end  


这个和post.rb非常类似。不同点就是这有个belongs_to :post.

这是activerecord的关系设置。你将会在下面学到更多关于设定表之间的关系。

除了增加模型之外,rails还生成了创建表的整合代码。

  1. class CreateComments < ActiveRecord::Migration  
  2.   def change  
  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.    
  11.     add_index :comments, :post_id  
  12.   end  
  13. end  

t.references这行是设定和post模型的外键。

add_index这行是设定这个外键作为索引。

继续向下进行db整合运行

  1. $ rake db:migrate  

rails是足够聪明的,他只运行DB中还没有运行的整合。

  1. ==  CreateComments: migrating =================================================  
  2. -- create_table(:comments)  
  3.    -> 0.0017s  
  4. ==  CreateComments: migrated (0.0018s) ========================================  


7.2 关联模型

ActiveRecord可以让你很简单的设定2个模型之间的关系。在comments和posts2个模型之间,

你可以通过这个方式写出他们的关系。

  • 每个comment 属于一个 post (1对1)
  • 一个post 有很多的 comments (1对多)

事实上,rails使用非常接近的语法来声明这种关系。你已经看到在comment模型代码中,

声明了每个comment属于一个post。

  1. class Comment < ActiveRecord::Base     
  2.   belongs_to :post  
  3. end   

 

你需要编辑post.rb模型代码来声明上面的一对多关系。

  1. class Post < ActiveRecord::Base     
  2.   validates :name,  :presence => true    
  3.   validates :title, :presence => true, :length => { :minimum => 5 }      
  4.    has_many :comments  
  5. end   


这2个声明可以使用很多自动行为。例如:如果你有一个实例变量

@post包含 一个post,你可以取得所有属于post的comments。通过

@post.comments方法返回一个数组。

7.3 给comments增加一个路由

像我们设置主页一样。我们需要增加一个路由来让我们导航可以浏览

comments。打开config/routes.rb文件,你将会发现posts已经在里面了。

这是由脚手架自动生成的。编辑他们像下面一样。

  1. resources :posts do   
  2.    resources :comments  
  3. end   

这个建立comments是一个posts的嵌套资源。捕捉post和comment之间存在层次关系另一部分


 7.4 产生一个控制器

模型产生完之后。是时候产生对应的控制器了。

  1. $ rails generate controller Comments   

这个命令产生了6个文件和一个空文件夹。

  • app/controllers/comments_controller.rb – 控制器
  • app/helpers/comments_helper.rb – 视图的帮助文件
  • test/functional/comments_controller_test.rb – 控制器的测试程序
  • test/unit/helpers/comments_helper_test.rb – 帮助的测试代码
  • app/views/comments/ – 控制器的视图代码放在这
  • app/assets/stylesheets/comment.css.scss – 控制器的样式
  • app/assets/javascripts/comment.js.coffee – 控制器的CoffeeScript

像很多博客一样,我们的读者将会创建评论在读完博客之后。一旦他们评论完,

将会调用post的显示页面,可以看到他们的评论。根据这些,我们的CommentsController

应该提供创建评论和删除垃圾评论的方法。

所以首先我们修改post的显示页面(/app/views/posts/show.html.erb)可以让我们增加评论

  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 %> |  

这个加进去的form是新建一个新的评论,将会调用
CommentsController的create方法。
  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   

你会看到这里面的处理会比post控制器的处理稍微复杂一点。这个设置了一个嵌套机制。每个评论都会跟随post。

所以在一开始进行了Post的查找。

 

同时,代码使用了模型关联的一些方法。我们使用@post.comments的create方法来新建保存评论。

这个将会自动连接comment因为他从属于post。

 

一旦我们新建完评论,我们将用户回到原来的页面通过post_path(@post)

正如我们所看到的,他将会调用PostsController的show动作,这时候我们希望

评论显示在此页面上。所以我们修改页面代码。

  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 %> |  


这样的话,你可以增加博客和评论,他们可以显示在正确的位置

posted @ 2013-08-08 10:58  wangyuyu  阅读(6612)  评论(0编辑  收藏  举报