FeaturesPluginsDocs & SupportCommunityPartners

构建 Rails 模型之间的关系

本教程介ç»?如何在 NetBeans Ruby on Rails 项目中构建模型之间的关系(一对一和多对一)。

目录

教程需求
创建样例数æ?®åº“
创建评论模型
è¿?移数æ?®åº“
定义评论模型和文章模型之间的关系
修改控制器脚手架
修改视图以添加评论
显示评论
本页é?¢çš„内容适用于 NetBeans IDE 6.0

教程需求

学习本教程需è¦?以下技术和资æº?:

创建样例数æ?®åº“

本教程基于教程 10 分钟创建 Ruby Weblog。如果您完æˆ?了那篇教程,那么您å?¯ä»¥å°†å®Œæˆ?教程时生æˆ?的项目作为起点,直接进入下一节。å?¦åˆ™ï¼Œè¯·æ‚¨å…ˆä¸‹è½½ RubyWebLog.zip 文件,然å?ŽæŒ‰ç…§ä¸‹é?¢çš„æ­¥éª¤åˆ›å»ºæ ·ä¾‹æ•°æ?®åº“。

注æ„?:本教程使用 MySQL 数æ?®åº“æœ?务器。您å?¯ä»¥å?‚考安装和é…?ç½® Ruby 支æŒ?一文以获å?–有关如何在 Ruby 应用程åº?中使用 MySQL 数æ?®åº“æœ?务器的信æ?¯ã€‚该文档å?Œæ ·ä»‹ç»?了如何使用 JavaDB 数æ?®åº“æœ?务器作为替代。
  1. 打开一个命令行窗å?£ã€‚
  2. 如果 MySQL 数æ?®åº“æœ?务器尚未被å?¯åŠ¨ï¼Œè¯·å…ˆå°†å…¶å?¯åŠ¨ã€‚
  3. 键入如下命令æ?¥åˆ›å»ºå¼€å?‘æ•°æ?®åº“,并按“Enterâ€?键。
    mysqladmin -u root -p create rubyweblog_development
    注æ„?:如果 root 用户ä¸?è¦?求密ç ?,请çœ?略 -p å?‚数。
  4. 在 IDE 中打开 rubyweblog 项目。

    注æ„?:如果是åˆ?次打开或者创建 Ruby 项目,IDE 会检查您是å?¦æœ‰é™¤äº†ç»‘定的 JRuby 软件之外其他的 Ruby 安装。如果有,IDE 会显示一个对è¯?框,询问您选择使用哪个软件。若您想è¦?使用绑定的 JRuby 解释器,选择 JRuby;或者您喜欢使用您自己的 Ruby 安装,那就选择您自己的安装。更多信æ?¯ï¼Œè¯·å?‚考《安装和é…?ç½® Ruby》教程中的é…?ç½® IDE 使用您自己的 Ruby 安装一节。
  5. 如果您的数æ?®åº“è¦?求密ç ?,请编缉 database.yml 文件,并在开å?‘é…?置部分中æ??供密ç ?。ä¿?存该文件。

    è¦?快速访问 database.yml 文件,按 Alt+Shift+O(在 Mac 系统中按 Ctrl+Shift+O),在“文件å??â€?文本框中键入 database.yml,然å?ŽæŒ‰â€œEnterâ€?键。
  6. å?³é”®ç‚¹å‡» rubyweblog 节点,选择“è¿?移数æ?®åº“â€?>“到当å‰?版本â€?。

    该æ“?作会更新数æ?®åº“以加入 posts 表并添加 body 字段。 è¿?移完æˆ?时会在“输出â€?窗å?£æ˜¾ç¤ºã€‚
  7. è¿?行应用程åº?å¹¶å?‘表一篇新文章。

创建评论模型

本教程通过增加å…?许读者给 blog 文章添加评论的功能扩充 rubyweblog 项目。首先è¦?创建评论模型æ?¥å­˜å‚¨è¯»è€…评论实例。而此项目中已ç»?有了存储 blog 文章实例的文章模型。
  1. 在“项目â€?窗å?£ä¸­ï¼Œå±•开“rubyweblogâ€?节点,å?³é”®ç‚¹å‡»â€œModelsâ€?节点,然å?Žé€‰æ‹©â€œGenerateâ€?。

  2. 在“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 了。
  1. 在“输出â€?窗å?£ä¸­ï¼Œç‚¹å‡» 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,文本æ??述。
  2. å?³é”®ç‚¹å‡» rubyweblog 节点,选择“è¿?移数æ?®åº“â€?>“到当å‰?版本â€?。

    该æ“?作会更新数æ?®åº“以加入 comments 表。 è¿?移完æˆ?时会在“输出â€?窗å?£æ˜¾ç¤ºã€‚

定义评论模型和文章模型之间的关系

应用程åº?目å‰?有两个模型:文章模型å?‘表一篇新的 blog 文章,而评论模型则å?‘一篇 blog 文章添加一æ?¡è¯„论。现在给两个模型之间定义关系, 使得一æ?¡è¯„论关è?”一篇文章,而一篇文章å?¯ä»¥åŒ…å?«å¤šæ?¡è¯„论。
  1. 展开“Modelsâ€?节点,打开 post.rb。
  2. 在 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。
  3. 打开“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 文章中创建ã€?读å?–ã€?更新和删除æ?¡ç›®çš„脚手架或者基本接å?£ã€‚
  1. 展开“Controllersâ€?节点,打开 blog_controller.rb。

    控制器拥有所有的脚手架动作,包括 indexã€?listã€?showã€?newã€?createã€?editã€?update 和 destroy。
  2. 如下é?¢çš„代ç ?示例所示,修改 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â€?称之)。
  3. 滚动至 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 æ?¡ç›®ã€‚
  1. 展开“Viewsâ€?> blog,然å?Žæ‰“å¼€ show.rhtml。
  2. 在 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 动作。
  3. ä¿?存文件,然å?Žè¿?行应用程åº?。
  4. 点击“Permalinkâ€?查看 blog æ?¡ç›®çš„详细信æ?¯ã€‚ 试ç?€åœ¨æ–‡æœ¬åŒºæ·»åР䏀æ?¡è¯„论,但是请留æ„?当点击“Postâ€?按钮时 blog 还ä¸?能显示评论。

    如果您的æ??交æˆ?功了,您å?¯ä»¥çœ‹åˆ°è§†å›¾é¡¶éƒ¨ä¼šæœ‰ä¸€æ?¡æ¶ˆæ?¯ï¼Œå¦‚下图所示。å?Žé?¢å‡ ä¸ªæ­¥éª¤ï¼Œæˆ‘们将添加代ç ?æ?¥æ”¶é›†å¹¶æ˜¾ç¤ºè¿™äº›è¯„论。

    图 1:没有显示评论的评论模型视图

    没有显示评论的评论模型视图

显示评论

blog 目å‰?还ä¸?能显示读者添加的评论,所以现在æ?¥è§£å†³è¿™ä¸ªé—®é¢˜ã€‚
  1. 在 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 æ?¥è®¿é—®ä¸€ç¯‡æ–‡ç« çš„æ‰€æœ‰è¯„论。
  2. 修改 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>
    
    

    此段代ç ?设定评论显示风格,以符å?ˆåˆ—表显示评论,å?Œæ—¶åŠ å…¥è¯„è®ºå?‘表的日期和时间。
  3. 选择“文件â€?>“全部ä¿?存â€?,然å?Žåˆ·æ–°æµ?览器。

    现在评论就以符å?·åˆ—表的形å¼?显示在 blog 中了,如下图所示。

    图 2:显示评论的评论模型视图

    图 2:显示评论的评论模型视图

更多内容


>> 更多 NetBeans Ruby 文档


Bookmark this page

del.icio.us furl simpy slashdot technorati digg
Companion
Projects:
MySQL Database Server   Open JDK: an Open SourceJDK   GlassFish Community: an Open Source Application Server    Mobile & Embedded Community    Open Solaris   java.net - The Source for Java Technology Collaboration   Open ESB - The Open Enterprise Service Bus Powered by