之前我们已经看到用脚手架运行的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. t.timestamps
  8. end
  9. add_index :comments, :post_id
  10. end
  11. 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. <p>
  3. <b>Name:</b>
  4. <%= @post.name %>
  5. </p>
  6. <p>
  7. <b>Title:</b>
  8. <%= @post.title %>
  9. </p>
  10. <p>
  11. <b>Content:</b>
  12. <%= @post.content %>
  13. </p>
  14. <h2>Add a comment:</h2>
  15. <%= form_for([@post, @post.comments.build]) do |f| %>
  16. <div class="field">
  17. <%= f.label :commenter %><br />
  18. <%= f.text_field :commenter %>
  19. </div>
  20. <div class="field">
  21. <%= f.label :body %><br />
  22. <%= f.text_area :body %>
  23. </div>
  24. <div class="actions">
  25. <%= f.submit %>
  26. </div>
  27. <% end %>
  28. <%= link_to 'Edit Post', edit_post_path(@post) %> |
  29. <%= 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. <p>
  3. <b>Name:</b>
  4. <%= @post.name %>
  5. </p>
  6. <p>
  7. <b>Title:</b>
  8. <%= @post.title %>
  9. </p>
  10. <p>
  11. <b>Content:</b>
  12. <%= @post.content %>
  13. </p>
  14. <h2>Comments</h2>
  15. <% @post.comments.each do |comment| %>
  16. <p>
  17. <b>Commenter:</b>
  18. <%= comment.commenter %>
  19. </p>
  20. <p>
  21. <b>Comment:</b>
  22. <%= comment.body %>
  23. </p>
  24. <% end %>
  25. <h2>Add a comment:</h2>
  26. <%= form_for([@post, @post.comments.build]) do |f| %>
  27. <div class="field">
  28. <%= f.label :commenter %><br />
  29. <%= f.text_field :commenter %>
  30. </div>
  31. <div class="field">
  32. <%= f.label :body %><br />
  33. <%= f.text_area :body %>
  34. </div>
  35. <div class="actions">
  36. <%= f.submit %>
  37. </div>
  38. <% end %>
  39. <br />
  40. <%= link_to 'Edit Post', edit_post_path(@post) %> |
  41. <%= link_to 'Back to Posts', posts_path %> |

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

Rails 增加一个模型(model)的更多相关文章

  1. phpcms 在后台增加了一个模型的话,在数据库中就会相应的增加数据库表

    在phpcms后台管理系统中,我们如果增加一个新的模型的话,例如名为:测试模型,英文名:test 在添加完成后,我们在数据库中发现增加了两个数据表:v9_test,v9_test_data;

  2. Rails 建立一个资源

    在blog 应用程序中.你可以通过脚手架(scaffolded)开始建立一个资源. 这将是单一的blog 提交.请输入以下命令 $ rails generate scaffold Post name: ...

  3. ASP.NET MVC 5 - 添加一个模型

    在本节中,您将添加一些类,这些类用于管理数据库中的电影.这些类是ASP.NET MVC 应用程序中的"模型(Model)". 您将使用.NET Framework 数据访问技术En ...

  4. 【再探backbone 01】模型-Model

    前言 点保存时候不注意发出来了,有需要的朋友将就看吧,还在更新...... 几个月前学习了一下backbone,这段时间也用了下,感觉之前对backbone的学习很是基础,前几天有个园友问我如何将路由 ...

  5. [转]ASP.NET MVC 5 - 添加一个模型

    在本节中,您将添加一些类,这些类用于管理数据库中的电影.这些类是ASP.NET MVC 应用程序中的"模型(Model)". 您将使用.NET Framework 数据访问技术En ...

  6. Django模型Model的定义

    概述 Django对各种数据库提供了很好的支持,Django为这些数据库提供了统一的调用API,可以根据不同的业务需求选择不同的数据库. 模型.属性.表.字段间的关系 一个模型类在数据库中对应一张表, ...

  7. Add an Item to the New Action 在新建按钮中增加一个条目

    In this lesson, you will learn how to add an item to the New Action (NewObjectViewController.NewObje ...

  8. Entity Framework 6 Recipes 2nd Edition(11-4)译 -> 在”模型定义”函数里调用另一个”模型定义”函数

    11-4.在”模型定义”函数里调用另一个”模型定义”函数 问题 想要用一个”模型定义”函数去实现另一个”模型定义”函数 解决方案 假设我们已有一个公司合伙人关系连同它们的结构模型,如Figure 11 ...

  9. Entity Framework 6 Recipes 2nd Edition(11-6)译 -> 从一个”模型定义”函数里返回一个复杂类型

    11-6.从一个”模型定义”函数里返回一个复杂类型 问题 想要从一个”模型定义”函数返回一个复杂类型 解决方案 假设我们有一个病人(patient)和他们访客(visit)的模型,如 Figure 1 ...

随机推荐

  1. 拷贝构造函数——防篡改

    对于普通类型的对象来说,他们之间的复制是简单的,比如: int a = 88; int b = a; 而类和普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量. #include <io ...

  2. 【算法34】蓄水池抽样算法 (Reservoir Sampling Algorithm)

    蓄水池抽样算法简介 蓄水池抽样算法随机算法的一种,用来从 N 个样本中随机选择 K 个样本,其中 N 非常大(以至于 N 个样本不能同时放入内存)或者 N 是一个未知数.其时间复杂度为 O(N),包含 ...

  3. Python学习-26.Python中的三角函数

    Python中的三角函数位于math模块内. 引入模块: import math 输出pi import math print(math.pi) 得:3.141592653589793 math模块内 ...

  4. web api 多版本控制重要的两个类

    1.版本路径替换 public class ReplaceVersionWithExactValueInPath : IDocumentFilter     {         public void ...

  5. Python - 更改pip源至国内镜像

    永久使用 [windows] 在用户名目录下创建一个目录 C:\Users\xxx\pip [linux] ~/.pip/pip.conf 新建pip.ini [global] index-url = ...

  6. ruby,gem,rails之间的关系

    Q:ruby,gem,rails之间的关系? 简单点说:Ruby是一种脚本语言,Gem是基于Ruby的一些开发工具包,Rails也算是一组Gem,专门用来做网站的.不同的Gem可能会依赖不同的Ruby ...

  7. 使用chosen插件实现多级联动和置位

    使用chosen插件实现多级联动和置位 首先写好第一个select,加上onchage属性之后,写onchange方法. <select data-placeholder="选择省份. ...

  8. Linq to sql中使用DateDiff()

    Linq to sql中使用DateDiff() 计算时间差的方法 第一种办法: from p in PurchaseLists where EntityFunctions.DiffDays(p.Cr ...

  9. [Xamarin]我的Xamarin填坑之旅(一)

    一想到明天是星期五,不对,是今天,心里就很激动,毕竟明天没课.激动之余,来写一篇博客,记录一下最近踏坑Xamarin开发校园助手APP的一些事儿.也许更像是一篇流水账. 在扯Xamarin之前,有必要 ...

  10. Sentinel 哨兵 实现redis高可用

    本文链接:http://www.cnblogs.com/zhenghongxin/p/8885879.html 我们知道redis是有主从复制的,例如下图: 但如果master主进程挂掉之后,没有sl ...