<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>blueplanet</title>
    <link>https://ruby-china.org/blueplanet</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>类似 “按照最新发布文章时间排序的用户列表” 的优雅的实现方法</title>
      <description>&lt;h2 id="前提"&gt;前提&lt;/h2&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;AR&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:posts&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;AR&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:user&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="问题"&gt;问题&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;想要实现用户的列表，按照用户最新发布的文章的时间排序&lt;/li&gt;
&lt;li&gt;用数据举例来说，如果有下列数据的话，希望显示的顺序是&lt;code&gt;user2 ; user1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user1
  post1 2015-03-01 00:00:00
  post2 2015-03-02 00:00:00
user2
  post11 2015-03-03 00:00:00
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="目前的实现方法"&gt;目前的实现方法&lt;/h2&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;scope :order_list, -&amp;gt; {
    select(&amp;lt;&amp;lt;-EOS
      users.*,
      (SELECT MAX(created_at) FROM posts WHERE users.id = posts.user_id) max_created_at
    EOS
      ).joins(:posts).
      order('max_created_at DESC').
      uniq
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;虽然使用直接嵌套 SQL 的方法实现了，总觉得应该有更优雅的实现方法，希望各路高手指教一下，谢谢！&lt;/strong&gt;&lt;/p&gt;</description>
      <author>blueplanet</author>
      <pubDate>Fri, 01 May 2015 08:30:39 +0800</pubDate>
      <link>https://ruby-china.org/topics/25394</link>
      <guid>https://ruby-china.org/topics/25394</guid>
    </item>
    <item>
      <title>[已解决] 使用 Ajax 时遇到了 InvalidAuthenticityToken 错误</title>
      <description>&lt;ul&gt;
&lt;li&gt;在 Rails 页面上使用 &lt;code&gt;$.Ajax&lt;/code&gt; 发送一个最简单的的&lt;code&gt;post&lt;/code&gt;请求，结果遇到了&lt;code&gt;InvalidAuthenticityToken&lt;/code&gt;错误&lt;/li&gt;
&lt;li&gt;如果使用&lt;code&gt;form_for ... remote:true&lt;/code&gt;的话完全正常&lt;/li&gt;
&lt;li&gt;我明白&lt;code&gt;Rails&lt;/code&gt;的&lt;code&gt;helper&lt;/code&gt;里面自动加了&lt;code&gt;X-CSRF-Token:&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="我的问题是：难道在不使用remote: true的时候，都需要自己在Ajax请求里面加上X-CSRF-Token:么？"&gt;我的问题是：难道在不使用&lt;code&gt;remote: true&lt;/code&gt;的时候，都需要自己在&lt;code&gt;Ajax&lt;/code&gt;请求里面加上&lt;code&gt;X-CSRF-Token:&lt;/code&gt;么？&lt;/h2&gt;&lt;h2 id="版本信息"&gt;版本信息&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;OS : MacOS 10.9.2&lt;/li&gt;
&lt;li&gt;Rails : 4.0.2&lt;/li&gt;
&lt;li&gt;Ruby : 2.0.0-p353&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="代码"&gt;代码&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;前提：&lt;code&gt;rails g scaffold posts title content:text&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;views/posts/index.html.erb&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form action="/posts" method="POST"&amp;gt;
  &amp;lt;input type="text" id="title"&amp;gt;
  &amp;lt;input type="submit" id="ajax_submit"&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;assets/javascript/posts.js.coffee&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ -&amp;gt;
  $('#ajax_submit').click (event) -&amp;gt;
    event.preventDefault() # 最开始的时候忘记加这句了，导致默认的提交动作也被执行了
    $.ajax(
      type: "POST"
      url: "/posts"
      data: {
        title: $('#post_title')
      }
      success: -&amp;gt;
        alert "success"
    )
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="分析过程（jquery_ujs.js）"&gt;分析过程（jquery_ujs.js）&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;首先，有一个&lt;code&gt;rails.CSRFProtection&lt;/code&gt;函数。它的作用就是向&lt;code&gt;ajax&lt;/code&gt;请求的&lt;code&gt;headers&lt;/code&gt;中加入&lt;code&gt;csrf token&lt;/code&gt;信息，代码如下&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CSRFProtection: function(xhr) {
  var token = $('meta[name="csrf-token"]').attr('content');
  if (token) xhr.setRequestHeader('X-CSRF-Token', token);
},
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;其次，第 290 行有如下的代码&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (rails.fire($document, 'rails:attachBindings')) { # 这句是触发`rails:attachBindings`事件
  $.ajaxPrefilter(function(options, originalOptions, xhr){ if ( !options.crossDomain ) { rails.CSRFProtection(xhr); }});
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;rails:attachBindings&lt;/code&gt;事件：查看&lt;code&gt;change log&lt;/code&gt;可以看到，是为了增加&lt;code&gt;$.rails&lt;/code&gt;的自定义设置。所以没有自定义的前提下，触发事件这句代码不会失败&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## 2.0.3 (16 August 2012)

  - Updated to latest jquery-ujs
    - created `rails:attachBindings` to allow for customization of $.rails object settings
    - created `ajax:send` event to provide access to jqXHR object from ajax requests
    - added support for `data-with-credentials`
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;也就意味着，&lt;code&gt;$.ajaxPrefilter(...&lt;/code&gt;这一句肯定会被执行&lt;/li&gt;
&lt;li&gt;也就是说：引入了&lt;code&gt;jquery_ujs.js&lt;/code&gt;的前提下，所有的&lt;code&gt;ajax&lt;/code&gt;请求都会自动被加入&lt;code&gt;csrf token&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="结论"&gt;结论&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;在&lt;code&gt;rails&lt;/code&gt;项目中，所有非跨站的&lt;code&gt;ajax&lt;/code&gt;请求都会被自动加入&lt;code&gt;csrf token&lt;/code&gt;信息，不需要自己去做&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>blueplanet</author>
      <pubDate>Fri, 07 Feb 2014 21:06:06 +0800</pubDate>
      <link>https://ruby-china.org/topics/17106</link>
      <guid>https://ruby-china.org/topics/17106</guid>
    </item>
    <item>
      <title>feature spec / integration spec ( request spec) / controller spec 的区别</title>
      <description>&lt;p&gt;如题。
最近写测试的时候开始有点晕，不知道&lt;code&gt;feature spec&lt;/code&gt; / &lt;code&gt;integration spec&lt;/code&gt; / &lt;code&gt;controller spec&lt;/code&gt;都应该测试什么&lt;/p&gt;

&lt;p&gt;比如说，有这样一个场景&lt;/p&gt;

&lt;p&gt;已登陆的用户，可以新建帖子&lt;/p&gt;

&lt;p&gt;那我的开发过程是这样的&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;新建一个&lt;code&gt;feature spec&lt;/code&gt;文件，使用&lt;code&gt;capybara&lt;/code&gt;来模拟上述内容
```
feature '已登录的用户，可以新建帖子' do
include_context '用户登录'
before { visit new_topic_path }&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;scenario '选择社区，填写标题和正文后，点击保存，可以新建一个帖子' do
    expect { 
      select 'Testing', from: 'topic_node'
      fill_in 'topic_title', with: '测试'
      fill_in 'topic_content', with: '测试正文'
      click_button '保存'
    }.to change(Topic, :count).by(1)
  end
end&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
* 然后执行测试，根据失败提示来继续开发
* 我原本是只写`feature`的测试来保证覆盖率的，有高手说，`feature`只测试功能，应该用`unit spec'来保证测试覆盖率
  * OK。那我把原来写在`feature`里面的各种验证的测试都改成`unit spec`，也就是`controller spec`, `model spec`，`feature spec`里面只保留基本的正常流程的`spec`。

### 到这里为止我还都理解。但之后就有点糊涂了。如果这样的话，那`request spec` 里面应该写哪些测试呢？
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>blueplanet</author>
      <pubDate>Wed, 03 Jul 2013 20:25:14 +0800</pubDate>
      <link>https://ruby-china.org/topics/12220</link>
      <guid>https://ruby-china.org/topics/12220</guid>
    </item>
    <item>
      <title>ruby-china 里面，ajax 如何实现的？</title>
      <description>&lt;p&gt;这两天在重看 &lt;a href="/huacnlee" class="user-mention" title="@huacnlee"&gt;&lt;i&gt;@&lt;/i&gt;huacnlee&lt;/a&gt; 的视频
&lt;a href="http://railscasts-china.com/episodes/live-show-with-huacnlee" rel="nofollow" target="_blank"&gt;http://railscasts-china.com/episodes/live-show-with-huacnlee&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;我的理解是这样的：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;在&lt;code&gt;topics/show.html.erb&lt;/code&gt;里面调用&lt;code&gt;topics_helper.rb&lt;/code&gt;的方法，生成了一个 Link&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;link_to raw([icon,"关注"].join(" ")), "#", :onclick =&amp;gt; "return Topics.follow(this);",
                    'data-id' =&amp;gt; topic.id,
                    'data-followed' =&amp;gt; (class_name == "followed"),
                    :rel =&amp;gt; "twipsy"
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在&lt;code&gt;topics.coffee&lt;/code&gt;里面定义了&lt;code&gt;Topics.fllow&lt;/code&gt;这个事件（函数？）&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# TopicsController 下所有页面的 JS 功能
window.Topics =
...
follow : (el) -&amp;gt;
topic_id = $(el).data("id")
followed = $(el).data("followed")
if followed
  $.ajax
    url : "/topics/#{topic_id}/unfollow"
    type : "POST"
  $(el).data("followed", false)
  $("i",el).attr("class", "icon small_follow")
else
  $.ajax
    url : "/topics/#{topic_id}/follow"
    type : "POST"
  $(el).data("followed", true)
  $("i",el).attr("class", "icon small_followed")
false
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;

&lt;p&gt;到这里我没弄明白的是&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;windows.Topics = ...&lt;/code&gt; 这句话是定义了一个变量？&lt;/li&gt;
&lt;li&gt;如果我自己想实现一个最简单的&lt;code&gt;js&lt;/code&gt;的&lt;code&gt;hello world&lt;/code&gt;的话，只需要这两步就可以么？&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;实际上我自己尝试了一下，但没有成功&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rails new coffee_test&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rails g controller topics index&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;在&lt;code&gt;topics/index.html.erb&lt;/code&gt;里面生成 Link
&lt;code&gt;
&amp;lt;%= link_to 'test', “#", :onclick =&amp;gt; "return Topics.sayHello();" %&amp;gt;
&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在&lt;code&gt;topics.coffee&lt;/code&gt;里面定义函数&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;windows.Topics = 
sayHello: -&amp;gt;
alert('Topics say : hello!!!')
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;打开&lt;code&gt;localhost:3000/topics/index&lt;/code&gt;后，点击&lt;code&gt;test&lt;/code&gt;完全没反映，也没有 JS 错误&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;请问我的理解哪里出错了？&lt;/p&gt;</description>
      <author>blueplanet</author>
      <pubDate>Wed, 26 Jun 2013 22:20:19 +0800</pubDate>
      <link>https://ruby-china.org/topics/12015</link>
      <guid>https://ruby-china.org/topics/12015</guid>
    </item>
    <item>
      <title>类似性别选项这样的固定分类如何做 i18n 国际化对应</title>
      <description>&lt;ul&gt;
&lt;li&gt;对整个网站来说是固定的分类，不需要用户或者管理员来维护。所以我觉得不应该做成单独的 model&lt;/li&gt;
&lt;li&gt;显示时是男／女，但数据库里保存的应该是 0／1 或者英文的 code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;想请教大家，在做类似这样的分类的时候是如何做国际化对应的呢？&lt;/p&gt;</description>
      <author>blueplanet</author>
      <pubDate>Sat, 22 Jun 2013 06:53:20 +0800</pubDate>
      <link>https://ruby-china.org/topics/11896</link>
      <guid>https://ruby-china.org/topics/11896</guid>
    </item>
    <item>
      <title>网页上想要的效果和 Model 的对应关系弄不明白了</title>
      <description>&lt;h3 id="网页上想要的效果"&gt;网页上想要的效果&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;想做的功能

&lt;ul&gt;
&lt;li&gt;三个人想要聚会，选了两个备选日期&lt;/li&gt;
&lt;li&gt;大家各自输入自己的两个日期的参加可否情况&lt;/li&gt;
&lt;li&gt;最后选出可能参加人数最多的日期来聚会&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;设想的界面&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;每一行是一个备选日期&lt;/li&gt;
&lt;li&gt;每一列是一个参加者&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;每一个单元格是参加者的备选日的参加可否情况&lt;/p&gt;
&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;甲&lt;/th&gt;
&lt;th&gt;乙&lt;/th&gt;
&lt;th&gt;丙&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2013/01/31&lt;/td&gt;
&lt;td&gt;○&lt;/td&gt;
&lt;td&gt;☓&lt;/td&gt;
&lt;td&gt;ー&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2013/02/01&lt;/td&gt;
&lt;td&gt;△&lt;/td&gt;
&lt;td&gt;ー&lt;/td&gt;
&lt;td&gt;○&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="定义的模型"&gt;定义的模型&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Event&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:days&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:users&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:statuses&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="sc"&gt;??&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;方案2&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Day&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;statuses&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="sc"&gt;??&lt;/span&gt; &lt;span class="n"&gt;方案1&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Status&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:day&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="sc"&gt;??&lt;/span&gt; &lt;span class="n"&gt;方案1&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="sc"&gt;??&lt;/span&gt; &lt;span class="n"&gt;方案2&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="我的问题"&gt;我的问题&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;单纯从模型来看，我认为应该把&lt;code&gt;Event&lt;/code&gt;和&lt;code&gt;Status&lt;/code&gt;做成 1:n 的关系&lt;/li&gt;
&lt;li&gt;可是在 view 里面看的时候，如果&lt;code&gt;Day&lt;/code&gt;和&lt;code&gt;Status&lt;/code&gt;做成 1:n 的关系的话我知道怎么实现；如果是&lt;code&gt;Event&lt;/code&gt;和&lt;code&gt;Status&lt;/code&gt;是 1:n 的话，不知道应该怎么实现&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;我现在的问题是&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;不知道方案 2 中，在 Event 中定义&lt;code&gt;has_many :statuses&lt;/code&gt;之后，还应该怎样定义一个方法才能实现&lt;code&gt;@event.statuses[row][col]&lt;/code&gt;这样的写法？&lt;/li&gt;
&lt;li&gt;如果是你的话，选哪种实现方法？&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="方案1: Day 和 Status 1:n"&gt;方案 1: Day 和 Status 1:n&lt;/h4&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;tbody&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="vi"&gt;@event.days.size.times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;tr&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;td&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"rowItem&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@event.days&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;
      &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="vi"&gt;@event.users.size.times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;td&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@event.days&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;statuses&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="方案2: Event 和 Status 1:n"&gt;方案 2: Event 和 Status 1:n&lt;/h4&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;tbody&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="vi"&gt;@event.days.size.times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;tr&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;td&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"rowItem&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@event.days&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;
      &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="vi"&gt;@event.users.size.times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;td&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@event.statuses&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>blueplanet</author>
      <pubDate>Mon, 28 Jan 2013 06:27:52 +0800</pubDate>
      <link>https://ruby-china.org/topics/8420</link>
      <guid>https://ruby-china.org/topics/8420</guid>
    </item>
    <item>
      <title>[已解决] 貌似 RSS 不更新了？</title>
      <description>&lt;p&gt;在 google reader 订阅的 RSS，最新的是 1 月 6 日的&lt;a href="http://ruby-china.org/topics/7816" title=""&gt;《Rails3 in Action》真是一本好书！&lt;/a&gt;，之后就再没有更新。&lt;/p&gt;

&lt;p&gt;是我自己的问题么？&lt;/p&gt;</description>
      <author>blueplanet</author>
      <pubDate>Wed, 16 Jan 2013 05:35:34 +0800</pubDate>
      <link>https://ruby-china.org/topics/8102</link>
      <guid>https://ruby-china.org/topics/8102</guid>
    </item>
    <item>
      <title>使用 RSpec+Capybara 简单 BDD 入门 -11</title>
      <description>&lt;p&gt;目录：&lt;a href="http://ruby-china.org/topics/7770" rel="nofollow" target="_blank"&gt;http://ruby-china.org/topics/7770&lt;/a&gt;
上一步：&lt;a href="http://ruby-china.org/topics/7785" title=""&gt;使用 RSpec+Capybara 简单 BDD 入门 -10&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="用户故事"&gt;用户故事&lt;/h2&gt;
&lt;p&gt;用户希望对帖子进行回复&lt;/p&gt;
&lt;h2 id="环境准备"&gt;环境准备&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; f11
rails c &lt;span class="c"&gt;# console&lt;/span&gt;
rails s &lt;span class="c"&gt;# server&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="步骤"&gt;步骤&lt;/h2&gt;&lt;h3 id="编辑spec/features/guest_can_see_topic_info_spec.rb，增加回复form的验证部分"&gt;编辑&lt;code&gt;spec/features/guest_can_see_topic_info_spec.rb&lt;/code&gt;，增加回复 form 的验证部分&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'应该显示回复用的form'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s2"&gt;"/topics/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@topic.id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

  &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_field&lt;/span&gt; &lt;span class="s1"&gt;'reply_content'&lt;/span&gt;
  &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_button&lt;/span&gt; &lt;span class="s1"&gt;'提交回复'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;expected to find field "replay_content" but there were no matches&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有实现的代码&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑topics/show.html.haml"&gt;编辑&lt;code&gt;topics/show.html.haml&lt;/code&gt;
&lt;/h3&gt;
&lt;p&gt;拷贝&lt;code&gt;ui/topic.html&lt;/code&gt;中回复 form 的部分至当前模板&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#reply.box&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"post"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;textarea&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"4"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"submit"&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"btn btn-primary"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"提交回复"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;修改为&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#reply.box&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form_for&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="vi"&gt;@topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Reply&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text_area&lt;/span&gt; &lt;span class="ss"&gt;:content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;rows: &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;submit&lt;/span&gt; &lt;span class="s2"&gt;"提交回复"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"btn btn-primary"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined methodtopic_replies_path' for #&amp;lt;#&amp;lt;Class:0x007fc0f8&lt;/code&gt;`&lt;/li&gt;
&lt;li&gt;原因：没有设置路由信息&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑config/routes.rb，增加嵌套的replay的路由设置"&gt;编辑&lt;code&gt;config/routes.rb&lt;/code&gt;，增加嵌套的 replay 的路由设置&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:topics&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:show&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:new&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:create&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:replies&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:create&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试通过！&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="增加提交回复的测试用例"&gt;增加提交回复的测试用例&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;scenario '输入回复内容点击"提交回复"后，正常提交回复' do
  visit "/topics/#{@topic.id}"

  fill_in 'reply_content', with: "回复测试"
  click_button "提交回复"

  current_path.should == topic_path(@topic)
  page.should have_content "回复测试"
end
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;uninitialized constant RepliesController&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;replies&lt;/code&gt;这个&lt;code&gt;controller&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="在rails console中执行"&gt;在&lt;code&gt;rails console&lt;/code&gt;中执行&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;34&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="s2"&gt;"controller replies"&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;  &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;controllers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;replies_controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
      &lt;span class="n"&gt;invoke&lt;/span&gt;  &lt;span class="n"&gt;haml&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;replies&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Completed"&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;The action 'create' could not be found for RepliesController&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;create&lt;/code&gt;方法&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑controllers/replies_controller.rb，增加create方法"&gt;编辑&lt;code&gt;controllers/replies_controller.rb&lt;/code&gt;，增加&lt;code&gt;create&lt;/code&gt;方法&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Missing template replies/create, application/create with {:local...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;replies/create&lt;/code&gt;模板&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑controllers/replies_controller.rb，增加实际逻辑"&gt;编辑&lt;code&gt;controllers/replies_controller.rb&lt;/code&gt;，增加实际逻辑&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RepliesController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;
    &lt;span class="n"&gt;topic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:topic_id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;reply&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:reply&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;
    &lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;

    &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试通过！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="完成，提交代码"&gt;完成，提交代码&lt;/h2&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nf"&gt;git&lt;/span&gt; &lt;span class="n"&gt;commit&lt;/span&gt; 
&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;checkout&lt;/span&gt; &lt;span class="n"&gt;dev&lt;/span&gt;
&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;merge&lt;/span&gt; &lt;span class="n"&gt;f11&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;no&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ff&lt;/span&gt;
&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;branch&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="n"&gt;f11&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;!! 全部完成!!&lt;/strong&gt;&lt;/p&gt;</description>
      <author>blueplanet</author>
      <pubDate>Sat, 05 Jan 2013 22:05:50 +0800</pubDate>
      <link>https://ruby-china.org/topics/7787</link>
      <guid>https://ruby-china.org/topics/7787</guid>
    </item>
    <item>
      <title>使用 RSpec+Capybara 简单 BDD 入门 -10</title>
      <description>&lt;p&gt;目录：&lt;a href="http://ruby-china.org/topics/7770" rel="nofollow" target="_blank"&gt;http://ruby-china.org/topics/7770&lt;/a&gt;
上一步：&lt;a href="http://ruby-china.org/topics/7782" title=""&gt;使用 RSpec+Capybara 简单 BDD 入门 -9&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="用户故事"&gt;用户故事&lt;/h2&gt;
&lt;p&gt;用户希望看到最新回复的信息&lt;/p&gt;

&lt;p&gt;帖子列表页面上显示最新回复的信息&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;回复人&lt;/li&gt;
&lt;li&gt;回复日期&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;补充：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;实际的目的是把回复和用户关联起来&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="环境准备"&gt;环境准备&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; f10
rails c &lt;span class="c"&gt;# console&lt;/span&gt;
rails s &lt;span class="c"&gt;# server&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="步骤"&gt;步骤&lt;/h2&gt;&lt;h3 id="编辑spec/features/topics_spec.rb，增加最新回复的验证部分"&gt;编辑&lt;code&gt;spec/features/topics_spec.rb&lt;/code&gt;，增加最新回复的验证部分&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'应该显示帖子的最新回复的信息'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="s2"&gt;"last replied by &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@user.name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; less than a minute ago"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;expected there to be text "last replied by test_user less than a minute ago" i...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：还没有实现具体的代码&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑topics/_topics.html.haml"&gt;编辑&lt;code&gt;topics/_topics.html.haml&lt;/code&gt;
&lt;/h3&gt;
&lt;p&gt;拷贝&lt;code&gt;ui/topics.html&lt;/code&gt;中最新回复的部分至当前模板&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"  •  "&lt;/span&gt;
&lt;span class="n"&gt;last&lt;/span&gt; &lt;span class="n"&gt;replied&lt;/span&gt; &lt;span class="n"&gt;by&lt;/span&gt;
&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"knwang"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"user_link"&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="n"&gt;mintes&lt;/span&gt; &lt;span class="n"&gt;ago&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;修改为&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;last_replay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;last&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;last_replay&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"  •  "&lt;/span&gt;
  &lt;span class="n"&gt;last&lt;/span&gt; &lt;span class="n"&gt;replied&lt;/span&gt; &lt;span class="n"&gt;by&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="n"&gt;last_replay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last_replay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"user_link"&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;time_ago_in_words&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;last_replay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; ago"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在测试用例的&lt;code&gt;background&lt;/code&gt;部分加入&lt;code&gt;replay&lt;/code&gt;的数据&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;last&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;content: &lt;/span&gt;&lt;span class="s1"&gt;'test replay'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;user: &lt;/span&gt;&lt;span class="vi"&gt;@user&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Can't mass-assign protected attributes: user&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有设置&lt;code&gt;user&lt;/code&gt;的访问属性&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑models/reply.rb，增加用户关联并设置访问属性"&gt;编辑&lt;code&gt;models/reply.rb&lt;/code&gt;，增加用户关联并设置访问属性&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Reply&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;attr_accessible&lt;/span&gt; &lt;span class="ss"&gt;:content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:user&lt;/span&gt;

  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:topic&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:user&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="在rails console中执行"&gt;在&lt;code&gt;rails console&lt;/code&gt;中执行&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="s2"&gt;"migration AddUserIdToReplies user_id:integer"&lt;/span&gt;
      &lt;span class="n"&gt;invoke&lt;/span&gt;  &lt;span class="n"&gt;active_record&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;migrate&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;20130103120615&lt;/span&gt;&lt;span class="n"&gt;_add_user_id_to_replies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Completed"&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="执行数据库升级"&gt;执行数据库升级&lt;/h3&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake db:migrate
bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake db:test:prepare
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试通过！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="完成，提交代码"&gt;完成，提交代码&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit 
git checkout dev
git merge f10 &lt;span class="nt"&gt;--no-ff&lt;/span&gt;
git branch &lt;span class="nt"&gt;-d&lt;/span&gt; f10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下一步骤：&lt;a href="http://ruby-china.org/topics/7787" title=""&gt;使用 RSpec+Capybara 简单 BDD 入门 -11&lt;/a&gt;&lt;/p&gt;</description>
      <author>blueplanet</author>
      <pubDate>Sat, 05 Jan 2013 21:59:52 +0800</pubDate>
      <link>https://ruby-china.org/topics/7785</link>
      <guid>https://ruby-china.org/topics/7785</guid>
    </item>
    <item>
      <title>使用 RSpec+Capybara 简单 BDD 入门 -9</title>
      <description>&lt;p&gt;目录：&lt;a href="http://ruby-china.org/topics/7770" rel="nofollow" target="_blank"&gt;http://ruby-china.org/topics/7770&lt;/a&gt;
上一步：&lt;a href="http://ruby-china.org/topics/7781" title=""&gt;使用 RSpec+Capybara 简单 BDD 入门 -7&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="用户故事"&gt;用户故事&lt;/h2&gt;
&lt;p&gt;用户希望看到帖子的回复列表&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;显示帖子的回复数量&lt;/li&gt;
&lt;li&gt;显示回复的下列信息

&lt;ul&gt;
&lt;li&gt;回复日期时间&lt;/li&gt;
&lt;li&gt;回复内容&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="环境准备"&gt;环境准备&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; f9
rails c &lt;span class="c"&gt;# console&lt;/span&gt;
rails s &lt;span class="c"&gt;# server&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="步骤"&gt;步骤&lt;/h2&gt;&lt;h3 id="编辑spec/features/guest_can_see_topic_info_spec.rb，增加回复部分的验证"&gt;编辑&lt;code&gt;spec/features/guest_can_see_topic_info_spec.rb&lt;/code&gt;，增加回复部分的验证&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'应该显示帖子的回复信息'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s2"&gt;"/topics/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@topic.id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

  &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="s2"&gt;"共收到 5 条回复"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;expected there to be text "共收到 5 条回复" in "社区 会员...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：还没有实现代码&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑topics/show.html.haml"&gt;编辑&lt;code&gt;topics/show.html.haml&lt;/code&gt;
&lt;/h3&gt;
&lt;p&gt;拷贝&lt;code&gt;ui/topic.html.haml&lt;/code&gt;的回复部分到当前模板&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#topic_content.box&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@topic.content&lt;/span&gt;

  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#replies_banner.box.info-box&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="n"&gt;共收到&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="n"&gt;条回复&lt;/span&gt;

  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#replies.box&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;ul&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;span1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;gravatar_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'joe@example.com'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;span8&lt;/span&gt;
          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"knwang"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"user_link"&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="n"&gt;two&lt;/span&gt; &lt;span class="n"&gt;hours&lt;/span&gt; &lt;span class="n"&gt;ago&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="n"&gt;这个操作就是罪恶的源泉&lt;/span&gt;&lt;span class="err"&gt;。。&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="n"&gt;这个操作就是罪恶的源泉&lt;/span&gt;&lt;span class="err"&gt;。。&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="n"&gt;这个操作就是罪恶的源泉&lt;/span&gt;&lt;span class="err"&gt;。。&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="n"&gt;这个操作就是罪恶的源泉&lt;/span&gt;&lt;span class="err"&gt;。。&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="n"&gt;这个操作就是罪恶的源泉&lt;/span&gt;&lt;span class="err"&gt;。。&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="n"&gt;这个操作就是罪恶的源泉&lt;/span&gt;&lt;span class="err"&gt;。。&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;span1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;gravatar_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'joe@example.com'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;span8&lt;/span&gt;
          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"knwang"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"user_link"&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="n"&gt;two&lt;/span&gt; &lt;span class="n"&gt;hours&lt;/span&gt; &lt;span class="n"&gt;ago&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="n"&gt;这个操作就是罪恶的源泉&lt;/span&gt;&lt;span class="err"&gt;。。&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;span1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;gravatar_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'joe@example.com'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;span8&lt;/span&gt;
          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"knwang"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"user_link"&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="n"&gt;two&lt;/span&gt; &lt;span class="n"&gt;hours&lt;/span&gt; &lt;span class="n"&gt;ago&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="n"&gt;这个操作就是罪恶的源泉&lt;/span&gt;&lt;span class="err"&gt;。。&lt;/span&gt;


&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#sidebar&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#new_topic.box&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;并修改为&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#topic_content.box&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@topic.content&lt;/span&gt;

  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#replies_banner.box.info-box&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"共收到 &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@topic.replies.count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 条回复"&lt;/span&gt;

  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#replies.box&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;ul&lt;/span&gt;
      &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="vi"&gt;@topic.replies.each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;span1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;gravatar_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'joe@example.com'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;span8&lt;/span&gt;
            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"knwang"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"user_link"&lt;/span&gt;
            &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;time_ago_in_words&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; ago"&lt;/span&gt;
            &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;content&lt;/span&gt; 

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#sidebar&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#new_topic.box&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;注意：回复的&lt;code&gt;user&lt;/code&gt;暂时先不考虑&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined methodreplies' for #Topic:0x007fc0f5c4b3b0...&lt;/code&gt;`&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;replies&lt;/code&gt;定义&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑models/topic.rb，增加关联定义"&gt;编辑&lt;code&gt;models/topic.rb&lt;/code&gt;，增加关联定义&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:replies&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;uninitialized constant Topic::Reply&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;Reply&lt;/code&gt;这个&lt;code&gt;model&lt;/code&gt;的定义&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="在rails console中执行"&gt;在&lt;code&gt;rails console&lt;/code&gt;中执行&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="s2"&gt;"model reply content:text topic_id:integer"&lt;/span&gt;
      &lt;span class="n"&gt;invoke&lt;/span&gt;  &lt;span class="n"&gt;active_record&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;migrate&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;20130103064335&lt;/span&gt;&lt;span class="n"&gt;_create_replies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Completed"&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="执行数据库升级"&gt;执行数据库升级&lt;/h3&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake db:migrate
bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake db:test:prepare
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="修改spec文件"&gt;修改 spec 文件&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="s1"&gt;'访问者希望看到帖子的详细信息'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="vi"&gt;@node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"Ruby"&lt;/span&gt;
    &lt;span class="vi"&gt;@topic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"topic 1 test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;content: &lt;/span&gt;&lt;span class="s2"&gt;"topic 1 content"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="vi"&gt;@node&lt;/span&gt;

    &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_index&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Reply&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;content: &lt;/span&gt;&lt;span class="s2"&gt;"reply &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;topic: &lt;/span&gt;&lt;span class="vi"&gt;@topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;user: &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'应该显示帖子的详细信息'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="o"&gt;......&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'应该显示帖子的回复信息'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s2"&gt;"/topics/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@topic.id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="s2"&gt;"共收到 &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@topic.replies.count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 条回复"&lt;/span&gt;

    &lt;span class="vi"&gt;@topic.replies.each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;content&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Can't mass-assign protected attributes: topic, user&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有设置&lt;code&gt;topic,user&lt;/code&gt;的访问属性&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑models/reply.rb，增加访问属性并设置topic和user的关联"&gt;编辑&lt;code&gt;models/reply.rb&lt;/code&gt;，增加访问属性并设置 topic 和 user 的关联&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Reply&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;attr_accessible&lt;/span&gt; &lt;span class="ss"&gt;:content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:topic&lt;/span&gt;

  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:topic&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试通过！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="完成，提交代码"&gt;完成，提交代码&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit 
git checkout dev
git merge f9 &lt;span class="nt"&gt;--no-ff&lt;/span&gt;
git branch &lt;span class="nt"&gt;-d&lt;/span&gt; f9
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下一步骤：&lt;a href="http://ruby-china.org/topics/7785" title=""&gt;使用 RSpec+Capybara 简单 BDD 入门 -10&lt;/a&gt;&lt;/p&gt;</description>
      <author>blueplanet</author>
      <pubDate>Sat, 05 Jan 2013 21:47:42 +0800</pubDate>
      <link>https://ruby-china.org/topics/7782</link>
      <guid>https://ruby-china.org/topics/7782</guid>
    </item>
    <item>
      <title>使用 RSpec+Capybara 简单 BDD 入门 -8</title>
      <description>&lt;p&gt;目录：&lt;a href="http://ruby-china.org/topics/7770" rel="nofollow" target="_blank"&gt;http://ruby-china.org/topics/7770&lt;/a&gt;
上一步：&lt;a href="http://ruby-china.org/topics/7780" title=""&gt;使用 RSpec+Capybara 简单 BDD 入门 -7&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="用户故事"&gt;用户故事&lt;/h2&gt;
&lt;p&gt;用户希望发布新帖&lt;/p&gt;

&lt;p&gt;输入下列项目&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;节点&lt;/li&gt;
&lt;li&gt;标题&lt;/li&gt;
&lt;li&gt;&lt;p&gt;内容
点击保存按钮后，显示帖子列表&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;帖子列表显示帖子创建者信息&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;在用户信息页面显示最新公开的帖子列表&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="环境准备"&gt;环境准备&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; f8
rails c &lt;span class="c"&gt;# console&lt;/span&gt;
rails s &lt;span class="c"&gt;# server&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="步骤"&gt;步骤&lt;/h2&gt;&lt;h3 id="新建文件spec/features/user_can_publish_topic_spec.rb"&gt;新建文件&lt;code&gt;spec/features/user_can_publish_topic_spec.rb&lt;/code&gt;
&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="s1"&gt;'用户希望公开帖子'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="vi"&gt;@user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'test_user'&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s1"&gt;'/sign_in'&lt;/span&gt;

    &lt;span class="n"&gt;fill_in&lt;/span&gt; &lt;span class="s1"&gt;'user_name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;with: &lt;/span&gt;&lt;span class="vi"&gt;@user.name&lt;/span&gt;
    &lt;span class="n"&gt;click_button&lt;/span&gt; &lt;span class="s2"&gt;"登录"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'访问/topics/new，应该显示新建帖子页面'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;click_link&lt;/span&gt; &lt;span class="s2"&gt;"发布新帖"&lt;/span&gt;

    &lt;span class="n"&gt;current_path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;new_topic_path&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="s2"&gt;"新建帖子"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined local variable or methodnew_topic_path' for #&amp;lt;RSpec:...&lt;/code&gt;`&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;new_topic&lt;/code&gt;的路由信息&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑config/routes.rb，增加路由信息"&gt;编辑&lt;code&gt;config/routes.rb&lt;/code&gt;，增加路由信息&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:topics&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:show&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:new&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;expected there to be text "新建帖子" in "社区 会员...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：“新建帖子”的链接还没有加上&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑topics/index.html.haml"&gt;编辑&lt;code&gt;topics/index.html.haml&lt;/code&gt;
&lt;/h3&gt;
&lt;p&gt;修改第 10 行，增加链接&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"发布新帖"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_topic_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"btn btn-success"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;The action 'new' could not be found for TopicsController&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有定义&lt;code&gt;new&lt;/code&gt;方法&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑controllers/topics_controller.rb，增加new方法"&gt;编辑&lt;code&gt;controllers/topics_controller.rb&lt;/code&gt;，增加&lt;code&gt;new&lt;/code&gt;方法&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Missing template topics/new, application/new with {:locale=&amp;gt;...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;topics/new&lt;/code&gt;模板&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="新建topics/new.html.haml模板"&gt;新建&lt;code&gt;topics/new.html.haml&lt;/code&gt;模板&lt;/h3&gt;
&lt;p&gt;拷贝&lt;code&gt;ui/new_topic.html&lt;/code&gt;内容至当前文件&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;测试通过！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="确认用户故事，增加spec"&gt;确认用户故事，增加&lt;code&gt;spec&lt;/code&gt;
&lt;/h2&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="s1"&gt;'用户希望公开帖子'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="vi"&gt;@user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'test_user'&lt;/span&gt;

    &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"Ruby"&lt;/span&gt;
    &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"Rails"&lt;/span&gt;
    &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"XiaCheDan"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s1"&gt;'/sign_in'&lt;/span&gt;

    &lt;span class="n"&gt;fill_in&lt;/span&gt; &lt;span class="s1"&gt;'user_name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;with: &lt;/span&gt;&lt;span class="vi"&gt;@user.name&lt;/span&gt;
    &lt;span class="n"&gt;click_button&lt;/span&gt; &lt;span class="s2"&gt;"登录"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'访问/topics/new，应该显示新建帖子页面'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;click_link&lt;/span&gt; &lt;span class="s2"&gt;"发布新帖"&lt;/span&gt;

    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="s2"&gt;"新建帖子"&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_select&lt;/span&gt; &lt;span class="s2"&gt;"topic_node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;options: &lt;/span&gt;&lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_field&lt;/span&gt; &lt;span class="s1"&gt;'topic_title'&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_field&lt;/span&gt; &lt;span class="s1"&gt;'topic_content'&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;expected to find select box "topic_node" but there wer...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：模板还是写死的数据&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑topics/new.html.haml"&gt;编辑&lt;code&gt;topics/new.html.haml&lt;/code&gt;
&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="s1"&gt;'shared/breadcrumb'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;links: &lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"Home"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"社区"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"发帖"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#new_topic.box&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt; &lt;span class="n"&gt;新建帖子&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form_for&lt;/span&gt; &lt;span class="vi"&gt;@topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;html: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"form-horizontal"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;control&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;
      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;label&lt;/span&gt; &lt;span class="s2"&gt;"标题"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"control-label"&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;controls&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt; &lt;span class="ss"&gt;:node_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;select&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Ruby"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="no"&gt;Ruby&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Rails"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"XiaCheDan"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="no"&gt;XiaCheDan&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text_field&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;control&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;
      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;label&lt;/span&gt; &lt;span class="s2"&gt;"正文"&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;controls&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text_area&lt;/span&gt; &lt;span class="ss"&gt;:content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;rows: &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;submit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;
      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;submit&lt;/span&gt; &lt;span class="s2"&gt;"保存"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"btn btn-primary"&lt;/span&gt;
      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"取消"&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#sidebar&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#new_post_note.box&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt; &lt;span class="n"&gt;发帖说明&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;没啥可说的&lt;/span&gt;&lt;span class="err"&gt;，&lt;/span&gt;&lt;span class="n"&gt;发就是了&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined methodmodel_name' for NilClass:Class&lt;/code&gt;`&lt;/li&gt;
&lt;li&gt;原因：没有对&lt;code&gt;@topic&lt;/code&gt;变量赋值&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑controllers/topics_controller.rb"&gt;编辑&lt;code&gt;controllers/topics_controller.rb&lt;/code&gt;
&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;
  &lt;span class="vi"&gt;@topic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试通过！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="确认用户故事，增加spec"&gt;确认用户故事，增加 spec&lt;/h2&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="s1"&gt;'用户希望公开帖子'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="vi"&gt;@user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'test_user'&lt;/span&gt;

    &lt;span class="vi"&gt;@ruby_node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"Ruby"&lt;/span&gt;
    &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"Rails"&lt;/span&gt;
&lt;span class="o"&gt;.....&lt;/span&gt;
  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'输入节点、标题、内容，点击"保存"按钮，应该正常提交并显示帖子列表'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;click_link&lt;/span&gt; &lt;span class="s2"&gt;"发布新帖"&lt;/span&gt;

    &lt;span class="nb"&gt;select&lt;/span&gt; &lt;span class="vi"&gt;@ruby_node.name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;from: &lt;/span&gt;&lt;span class="s1"&gt;'topic_node_id'&lt;/span&gt;
    &lt;span class="n"&gt;fill_in&lt;/span&gt; &lt;span class="s1"&gt;'topic_title'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;with: &lt;/span&gt;&lt;span class="s1"&gt;'new topic title'&lt;/span&gt;
    &lt;span class="n"&gt;fill_in&lt;/span&gt; &lt;span class="s1"&gt;'topic_content'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;with: &lt;/span&gt;&lt;span class="s1"&gt;'new topic content'&lt;/span&gt;

    &lt;span class="n"&gt;click_button&lt;/span&gt; &lt;span class="s2"&gt;"保存"&lt;/span&gt;

    &lt;span class="n"&gt;current_path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;root_path&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="s1"&gt;'new topic title'&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;No route matches [POST] "/topics"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;topics#create&lt;/code&gt;的路由信息&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑config/routes.rb，增加路由信息"&gt;编辑&lt;code&gt;config/routes.rb&lt;/code&gt;，增加路由信息&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:topics&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:show&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:new&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:create&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;The action 'create' could not be found for TopicsController&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有定义&lt;code&gt;create&lt;/code&gt;方法&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑controllers/topics_controller.rb"&gt;编辑&lt;code&gt;controllers/topics_controller.rb&lt;/code&gt;
&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Missing template topics/create, application/create with {:loca...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;create&lt;/code&gt;模板。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑controllers/topics_controller.rb"&gt;编辑&lt;code&gt;controllers/topics_controller.rb&lt;/code&gt;
&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;
  &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:topic&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="n"&gt;root_path&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Can't mass-assign protected attributes: node_id&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有对&lt;code&gt;node_id&lt;/code&gt;的访问属性声明&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑model/topic.rb，增加属性声明"&gt;编辑&lt;code&gt;model/topic.rb&lt;/code&gt;，增加属性声明&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;attr_accessible&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:node_id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试通过！！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="重构"&gt;重构&lt;/h2&gt;
&lt;p&gt;spec 文件中，&lt;code&gt;click_link "发布新帖"&lt;/code&gt;可以移到&lt;code&gt;before&lt;/code&gt;里面&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s1"&gt;'/sign_in'&lt;/span&gt;

  &lt;span class="n"&gt;fill_in&lt;/span&gt; &lt;span class="s1"&gt;'user_name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;with: &lt;/span&gt;&lt;span class="vi"&gt;@user.name&lt;/span&gt;
  &lt;span class="n"&gt;click_button&lt;/span&gt; &lt;span class="s2"&gt;"登录"&lt;/span&gt;

  &lt;span class="n"&gt;click_link&lt;/span&gt; &lt;span class="s2"&gt;"发布新帖"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'访问/topics/new，应该显示新建帖子页面'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="s2"&gt;"新建帖子"&lt;/span&gt;
  &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_select&lt;/span&gt; &lt;span class="s2"&gt;"topic_node_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;options: &lt;/span&gt;&lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_field&lt;/span&gt; &lt;span class="s1"&gt;'topic_title'&lt;/span&gt;
  &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_field&lt;/span&gt; &lt;span class="s1"&gt;'topic_content'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'输入节点、标题、内容，点击"保存"按钮，应该正常提交并显示帖子列表'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nb"&gt;select&lt;/span&gt; &lt;span class="vi"&gt;@ruby_node.name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;from: &lt;/span&gt;&lt;span class="s1"&gt;'topic_node_id'&lt;/span&gt;
  &lt;span class="n"&gt;fill_in&lt;/span&gt; &lt;span class="s1"&gt;'topic_title'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;with: &lt;/span&gt;&lt;span class="s1"&gt;'new topic title'&lt;/span&gt;
  &lt;span class="n"&gt;fill_in&lt;/span&gt; &lt;span class="s1"&gt;'topic_content'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;with: &lt;/span&gt;&lt;span class="s1"&gt;'new topic content'&lt;/span&gt;

  &lt;span class="n"&gt;click_button&lt;/span&gt; &lt;span class="s2"&gt;"保存"&lt;/span&gt;

  &lt;span class="n"&gt;current_path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;root_path&lt;/span&gt;
  &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="s1"&gt;'new topic title'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试应该仍然全部通过&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="确认用户故事，修改spec"&gt;确认用户故事，修改 spec&lt;/h2&gt;&lt;h3 id="编辑spec/features/topics_spec.rb，增加帖子创建者的验证部分"&gt;编辑&lt;code&gt;spec/features/topics_spec.rb&lt;/code&gt;，增加帖子创建者的验证部分&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;第二行的 feature 描述错了，也顺便修改一下 :)&lt;/li&gt;
&lt;li&gt;顺便把重复的部分重构一下 :)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="s1"&gt;'访问者希望看到所有帖子'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"瞎扯淡"&lt;/span&gt;
    &lt;span class="vi"&gt;@user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'test_user'&lt;/span&gt;

    &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"DHH 的公开课"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;
    &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"Rails3 中 compass 的 IE 使用问题"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;
    &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"这周二上海搞Ruby Tuesday么？"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="s2"&gt;"访问/topics"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s1"&gt;'/topics'&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'应该显示所有帖子'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="s2"&gt;"published less than a minute ago"&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'应该显示帖子的节点名称'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'应该显示帖子创建者名称'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@user.name&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;expected there to be text "test_user" in "社区 会员...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：还没有显示创建者名称&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑topics/_topics.html.haml"&gt;编辑&lt;code&gt;topics/_topics.html.haml&lt;/code&gt;
&lt;/h3&gt;
&lt;p&gt;修改第 12 行&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"knwang"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"user_link"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;为&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;author&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"user_link"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined methodanthor' for #Topic:0x007fd32d943a60&lt;/code&gt;`&lt;/li&gt;
&lt;li&gt;原因：没有定义&lt;code&gt;author&lt;/code&gt;方法&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑models/topic.rb，增加author的声明"&gt;编辑&lt;code&gt;models/topic.rb&lt;/code&gt;，增加&lt;code&gt;author&lt;/code&gt;的声明&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:anthor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class_name: &lt;/span&gt;&lt;span class="s2"&gt;"User"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="在rails console中执行"&gt;在&lt;code&gt;rails console&lt;/code&gt;中执行&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="s2"&gt;"migration AddAuthorIdToTopics author_id:integer"&lt;/span&gt;
      &lt;span class="n"&gt;invoke&lt;/span&gt;  &lt;span class="n"&gt;active_record&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;migrate&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;20130102235735&lt;/span&gt;&lt;span class="n"&gt;_add_author_id_to_topics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Completed"&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="执行数据库升级"&gt;执行数据库升级&lt;/h3&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake db:migrate
bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake db:test:prepare
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="编辑spec，修改Topic，增加author的赋值部分"&gt;编辑&lt;code&gt;spec&lt;/code&gt;，修改&lt;code&gt;Topic&lt;/code&gt;，增加&lt;code&gt;author&lt;/code&gt;的赋值部分&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"DHH 的公开课"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;author: &lt;/span&gt;&lt;span class="vi"&gt;@user&lt;/span&gt;
&lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"Rails3 中 compass 的 IE 使用问题"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;author: &lt;/span&gt;&lt;span class="vi"&gt;@user&lt;/span&gt;
&lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"这周二上海搞Ruby Tuesday么？"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;author: &lt;/span&gt;&lt;span class="vi"&gt;@user&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Can't mass-assign protected attributes: author&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有设置&lt;code&gt;author&lt;/code&gt;的访问属性&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑models/topic.rb，增加访问属性声明"&gt;编辑&lt;code&gt;models/topic.rb&lt;/code&gt;，增加访问属性声明&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;attr_accessible&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:node_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:author&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;部分测试成功，但有其他的测试失败&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="编辑spec/features/user_can_publish_topic_spec.rb"&gt;编辑&lt;code&gt;spec/features/user_can_publish_topic_spec.rb&lt;/code&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;测试失败原因：公开帖子的时候没有设置&lt;code&gt;author&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;
  &lt;span class="n"&gt;topic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:topic&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;
  &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;

  &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="n"&gt;root_path&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试成功&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="编辑spec/features/nodes_spec.rb"&gt;编辑&lt;code&gt;spec/features/nodes_spec.rb&lt;/code&gt;
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;测试失败原因：数据准备部分没有设置&lt;code&gt;author&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'test_user'&lt;/span&gt;

  &lt;span class="vi"&gt;@node1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"Ruby Node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;description: &lt;/span&gt;&lt;span class="s2"&gt;"Ruby是一门优美的语言"&lt;/span&gt;
  &lt;span class="vi"&gt;@node2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"Rails Node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;description: &lt;/span&gt;&lt;span class="s2"&gt;"Rails是一个快速WEB开发框架"&lt;/span&gt;

  &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_index&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"topic &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="vi"&gt;@node1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;author: &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_index&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"topic &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="vi"&gt;@node2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;author: &lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试通过！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="再次确认用户故事，增加spec"&gt;再次确认用户故事，增加 spec&lt;/h2&gt;&lt;h3 id="编辑spec/features/guest_can_see_user_info_spec.rb，增加最新帖子的验证部分"&gt;编辑&lt;code&gt;spec/features/guest_can_see_user_info_spec.rb&lt;/code&gt;，增加最新帖子的验证部分&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="s1"&gt;'访问者希望看到用户的信息'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="vi"&gt;@user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"test_user"&lt;/span&gt;

    &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_index&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"topic &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;author: &lt;/span&gt;&lt;span class="vi"&gt;@user&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'访问/users/:id, 应该显示用户信息'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s2"&gt;"/users/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@user.id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@user.name&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@user.created_at.to_s&lt;/span&gt;

    &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;expected there to be text "topic 0" in "社区 会...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：还没有实现最新回复的部分&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑users/show.html.haml"&gt;编辑&lt;code&gt;users/show.html.haml&lt;/code&gt;
&lt;/h3&gt;
&lt;p&gt;拷贝&lt;code&gt;ui/user.html.haml&lt;/code&gt;中最新回复的部分至当前模板最下方&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#user_recent_topics.box&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#user_recent_topics_banner.box.info-box&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="n"&gt;最近发布的帖子&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#user_recent_topics_content.box&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;ul&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"Rails"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"BDD开发模式:使用Rspec开发Rails Project的标准流程是什么?"&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="n"&gt;ago&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"Rails"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"BDD开发模式:使用Rspec开发Rails Project的标准流程是什么?"&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="n"&gt;ago&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"Rails"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"BDD开发模式:使用Rspec开发Rails Project的标准流程是什么?"&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="n"&gt;ago&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;修改为&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#user_recent_topics.box&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#user_recent_topics_banner.box.info-box&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="n"&gt;最近发布的帖子&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#user_recent_topics_content.box&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;ul&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"Rails"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"BDD开发模式:使用Rspec开发Rails Project的标准流程是什么?"&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="n"&gt;ago&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"Rails"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"BDD开发模式:使用Rspec开发Rails Project的标准流程是什么?"&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="n"&gt;ago&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"Rails"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"BDD开发模式:使用Rspec开发Rails Project的标准流程是什么?"&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="n"&gt;ago&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined methodtopics' for #User:0x007fc0f7305830...&lt;/code&gt;`&lt;/li&gt;
&lt;li&gt;原因：&lt;code&gt;user&lt;/code&gt;还没有和&lt;code&gt;topic&lt;/code&gt;关联&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑models/user.rb，增加关联"&gt;编辑&lt;code&gt;models/user.rb&lt;/code&gt;，增加关联&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:topics&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:class_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Topic"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:foreign_key&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"author_id"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试通过！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="重构"&gt;重构&lt;/h2&gt;&lt;h3 id="编辑 spec/featurs/guest_can_see_user_info_spec.rb"&gt;编辑 &lt;code&gt;spec/featurs/guest_can_see_user_info_spec.rb&lt;/code&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;最新发布帖子的验证部分分到单独的&lt;code&gt;scenario&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;把重复的部分提取到&lt;code&gt;before&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="s1"&gt;'访问者希望看到用户的信息'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="vi"&gt;@user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"test_user"&lt;/span&gt;
    &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"ruby"&lt;/span&gt;

    &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_index&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"topic &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;author: &lt;/span&gt;&lt;span class="vi"&gt;@user&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s2"&gt;"/users/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@user.id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'应该显示用户信息'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@user.name&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@user.created_at.to_s&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'应该显示用户最新发布的帖子'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="补充重构（可以不做）"&gt;补充重构（可以不做）&lt;/h2&gt;&lt;h3 id="guest_can_sign_in_spec.rb中也有重复的代码可以重构"&gt;
&lt;code&gt;guest_can_sign_in_spec.rb&lt;/code&gt;中也有重复的代码可以重构&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'输入用户名后点击"登录"按钮，应该正常登录'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s2"&gt;"/sign_in"&lt;/span&gt;

  &lt;span class="n"&gt;fill_in&lt;/span&gt; &lt;span class="s2"&gt;"user_name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;with: &lt;/span&gt;&lt;span class="vi"&gt;@user.name&lt;/span&gt;
  &lt;span class="n"&gt;click_button&lt;/span&gt; &lt;span class="s2"&gt;"登录"&lt;/span&gt;

  &lt;span class="n"&gt;current_path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;root_path&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'应该显示用户名称'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s2"&gt;"/sign_in"&lt;/span&gt;

  &lt;span class="n"&gt;fill_in&lt;/span&gt; &lt;span class="s2"&gt;"user_name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;with: &lt;/span&gt;&lt;span class="vi"&gt;@user.name&lt;/span&gt;
  &lt;span class="n"&gt;click_button&lt;/span&gt; &lt;span class="s2"&gt;"登录"&lt;/span&gt;

  &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@user.name&lt;/span&gt;    
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以把重复的部分提取出来&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s2"&gt;"/sign_in"&lt;/span&gt;

    &lt;span class="n"&gt;fill_in&lt;/span&gt; &lt;span class="s2"&gt;"user_name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;with: &lt;/span&gt;&lt;span class="vi"&gt;@user.name&lt;/span&gt;
    &lt;span class="n"&gt;click_button&lt;/span&gt; &lt;span class="s2"&gt;"登录"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'输入用户名后点击"登录"按钮，应该正常登录'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;current_path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;root_path&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'应该显示用户名称'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@user.name&lt;/span&gt;    
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="完成，提交代码"&gt;完成，提交代码&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit 
git checkout dev
git merge f8 &lt;span class="nt"&gt;--no-ff&lt;/span&gt;
git branch &lt;span class="nt"&gt;-d&lt;/span&gt; f8
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下一步骤：&lt;a href="http://ruby-china.org/topics/7782" title=""&gt;使用 RSpec+Capybara 简单 BDD 入门 -9&lt;/a&gt;&lt;/p&gt;</description>
      <author>blueplanet</author>
      <pubDate>Sat, 05 Jan 2013 21:44:20 +0800</pubDate>
      <link>https://ruby-china.org/topics/7781</link>
      <guid>https://ruby-china.org/topics/7781</guid>
    </item>
    <item>
      <title>使用 RSpec+Capybara 简单 BDD 入门 -7</title>
      <description>&lt;p&gt;目录：&lt;a href="http://ruby-china.org/topics/7770" rel="nofollow" target="_blank"&gt;http://ruby-china.org/topics/7770&lt;/a&gt;
上一步：&lt;a href="http://ruby-china.org/topics/7779" title=""&gt;使用 RSpec+Capybara 简单 BDD 入门 -6&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="用户故事"&gt;用户故事&lt;/h2&gt;
&lt;p&gt;访问者希望登录&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;使用用户名登录&lt;/li&gt;
&lt;li&gt;登录后显示帖子列表&lt;/li&gt;
&lt;li&gt;在右上角显示用户名&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="环境准备"&gt;环境准备&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; f7
rails c &lt;span class="c"&gt;# console&lt;/span&gt;
rails s &lt;span class="c"&gt;# server&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="步骤"&gt;步骤&lt;/h2&gt;&lt;h3 id="新建文件spec/features/guest_can_sign_in_spec.rb"&gt;新建文件&lt;code&gt;spec/features/guest_can_sign_in_spec.rb&lt;/code&gt;
&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="s1"&gt;'访问者希望登录'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="vi"&gt;@user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"test_user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;email: &lt;/span&gt;&lt;span class="s2"&gt;"test@test.com"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'输入用户名后点击"登录"按钮，应该正常登录'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s2"&gt;"/sign_in"&lt;/span&gt;

    &lt;span class="n"&gt;fill_in&lt;/span&gt; &lt;span class="s2"&gt;"user_name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;with: &lt;/span&gt;&lt;span class="vi"&gt;@user.name&lt;/span&gt;
    &lt;span class="n"&gt;click_button&lt;/span&gt; &lt;span class="s2"&gt;"登录"&lt;/span&gt;

    &lt;span class="n"&gt;current_path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;root_path&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;No route matches [GET] "/sign_in"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;sign_in&lt;/code&gt;的路由信息&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑config/routes.rb，增加路由信息"&gt;编辑&lt;code&gt;config/routes.rb&lt;/code&gt;，增加路由信息&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;match 'sign_in', to: "sessions#new"
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;uninitialized constant SessionsController&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;sessions&lt;/code&gt;这个&lt;code&gt;controller&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="在rails console中执行"&gt;在&lt;code&gt;rails console&lt;/code&gt;中执行&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="s2"&gt;"controller sessions"&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;  &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;controllers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sessions_controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
      &lt;span class="n"&gt;invoke&lt;/span&gt;  &lt;span class="n"&gt;haml&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sessions&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Completed"&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;The action 'new' could not be found for SessionsController&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有定义&lt;code&gt;new&lt;/code&gt;方法&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑controllers/sessions_controller.rb，增加new方法"&gt;编辑&lt;code&gt;controllers/sessions_controller.rb&lt;/code&gt;，增加&lt;code&gt;new&lt;/code&gt;方法&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SessionsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Missing template sessions/new, application/new with {:lo...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有对应的&lt;code&gt;new&lt;/code&gt;模板&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="新建sessions/new.html.haml模板"&gt;新建&lt;code&gt;sessions/new.html.haml&lt;/code&gt;模板&lt;/h3&gt;
&lt;p&gt;拷贝&lt;code&gt;ui/signin.html&lt;/code&gt;内容至当前模板&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="s1"&gt;'shared/breadcrumb'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;links: &lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"Home"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#sign_in.box&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt; &lt;span class="n"&gt;登录&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"post"&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"form-horizontal"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;control&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"control-label"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;用户名&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;controls&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;submit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"submit"&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"登录"&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"btn btn-primary"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#sidebar&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#has_account.box&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt; &lt;span class="n"&gt;还没有帐号?&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"注册"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Unable to find field "user_name"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：模板还是写死的假数据&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="修改sessions/new.html.haml模板"&gt;修改&lt;code&gt;sessions/new.html.haml&lt;/code&gt;模板&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="s1"&gt;'shared/breadcrumb'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;links: &lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"Home"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#sign_in.box&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt; &lt;span class="n"&gt;登录&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form_tag&lt;/span&gt; &lt;span class="n"&gt;sessions_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;method: :post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"form-horizontal"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;control&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;
      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;label_tag&lt;/span&gt; &lt;span class="ss"&gt;:user_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"用户名"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"control-label"&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;controls&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;text_field_tag&lt;/span&gt; &lt;span class="ss"&gt;:user_name&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;submit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;
      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;submit_tag&lt;/span&gt; &lt;span class="s2"&gt;"登录"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"btn btn-primary"&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#sidebar&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#has_account.box&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt; &lt;span class="n"&gt;还没有帐号?&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"注册"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined local variable or methodsessions_path' for #&amp;lt;...&lt;/code&gt;`&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;sessions#create&lt;/code&gt;的路由信息&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑config/routes.rb，增加路由信息"&gt;编辑&lt;code&gt;config/routes.rb&lt;/code&gt;，增加路由信息&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:sessions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:create&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;The action 'create' could not be found for SessionsController&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有定义&lt;code&gt;create&lt;/code&gt;方法&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑controllers/sessions_controller，增加create方法"&gt;编辑&lt;code&gt;controllers/sessions_controller&lt;/code&gt;，增加&lt;code&gt;create&lt;/code&gt;方法&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Missing template sessions/create, application/create with {:l...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;sessions/create&lt;/code&gt;模板&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑controllers/sessions_controller，修改create方法内容"&gt;编辑&lt;code&gt;controllers/sessions_controller&lt;/code&gt;，修改&lt;code&gt;create&lt;/code&gt;方法内容&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;
  &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:user_name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:user_name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="n"&gt;root_path&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试通过！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="确认用户故事，增加spec"&gt;确认用户故事，增加 spec&lt;/h2&gt;&lt;h3 id="编辑spec/features/guest_can_sign_in_spec.rb"&gt;编辑&lt;code&gt;spec/features/guest_can_sign_in_spec.rb&lt;/code&gt;
&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'应该显示用户名称'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s2"&gt;"/sign_in"&lt;/span&gt;

  &lt;span class="n"&gt;fill_in&lt;/span&gt; &lt;span class="s2"&gt;"user_name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;with: &lt;/span&gt;&lt;span class="vi"&gt;@user.name&lt;/span&gt;
  &lt;span class="n"&gt;click_button&lt;/span&gt; &lt;span class="s2"&gt;"登录"&lt;/span&gt;

  &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@user.name&lt;/span&gt;    
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;expected there to be text "test_user" in "社区 会员 knowa...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：还没有写显示用户名称的代码&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑layouts/application.html.haml"&gt;编辑&lt;code&gt;layouts/application.html.haml&lt;/code&gt;
&lt;/h3&gt;
&lt;p&gt;把第 22 行 knowang 的部分修改为实际代码&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined local variable or methodcurrent_user' for #&amp;lt;...&lt;/code&gt;`&lt;/li&gt;
&lt;li&gt;原因：没有定义&lt;code&gt;current_user&lt;/code&gt;方法&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑controllers/application_controller.rb，增加current_user的定义"&gt;编辑&lt;code&gt;controllers/application_controller.rb&lt;/code&gt;，增加&lt;code&gt;current_user&lt;/code&gt;的定义&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ApplicationController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActionController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
  &lt;span class="n"&gt;protect_from_forgery&lt;/span&gt;

  &lt;span class="n"&gt;helper_method&lt;/span&gt; &lt;span class="ss"&gt;:current_user&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;current_user&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:user_name&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:user_name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试通过！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="完成，提交代码"&gt;完成，提交代码&lt;/h2&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git add .
git commit 
git checkout dev
git merge f7 --no-ff
git branch -d f7
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下一步骤：&lt;a href="http://ruby-china.org/topics/7781" title=""&gt;使用 RSpec+Capybara 简单 BDD 入门 -8&lt;/a&gt;&lt;/p&gt;</description>
      <author>blueplanet</author>
      <pubDate>Sat, 05 Jan 2013 21:25:52 +0800</pubDate>
      <link>https://ruby-china.org/topics/7780</link>
      <guid>https://ruby-china.org/topics/7780</guid>
    </item>
    <item>
      <title>使用 RSpec+Capybara 简单 BDD 入门 -6</title>
      <description>&lt;p&gt;目录：&lt;a href="http://ruby-china.org/topics/7770" rel="nofollow" target="_blank"&gt;http://ruby-china.org/topics/7770&lt;/a&gt;
上一步：&lt;a href="http://ruby-china.org/topics/7776" title=""&gt;使用 RSpec+Capybara 简单 BDD 入门 -5&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="用户故事"&gt;用户故事&lt;/h2&gt;
&lt;p&gt;访问者希望注册用户&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;通过用户名和 Email 注册&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="环境准备"&gt;环境准备&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; f6
rails c &lt;span class="c"&gt;# console&lt;/span&gt;
rails s &lt;span class="c"&gt;# server&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="步骤"&gt;步骤&lt;/h2&gt;&lt;h3 id="新建文件spec/features/guest_can_sign_up_spec.rb"&gt;新建文件&lt;code&gt;spec/features/guest_can_sign_up_spec.rb&lt;/code&gt;
&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="s1"&gt;'访问者希望注册用户'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'访问/sign_up, 应该显示注册用页面'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s1"&gt;'/sign_up'&lt;/span&gt;

    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_field&lt;/span&gt; &lt;span class="s2"&gt;"user_name"&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_field&lt;/span&gt; &lt;span class="s2"&gt;"user_email"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;No route matches [GET] "/sign_up"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;sign_up&lt;/code&gt;的路由信息&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑config/routes.rb，增加下列路由"&gt;编辑&lt;code&gt;config/routes.rb&lt;/code&gt;，增加下列路由&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="s1"&gt;'sign_up'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s2"&gt;"users#new"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;The action 'new' could not be found for UsersController&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：&lt;code&gt;users_controller&lt;/code&gt;没有&lt;code&gt;new&lt;/code&gt;方法&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑controllers/users_controlelr.rb，增加new方法"&gt;编辑&lt;code&gt;controllers/users_controlelr.rb&lt;/code&gt;，增加&lt;code&gt;new&lt;/code&gt;方法&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UsersController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show&lt;/span&gt;
    &lt;span class="vi"&gt;@user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Missing template users/new, application/new with {:locale=&amp;gt;[:e...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;new&lt;/code&gt;模板&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="新建users/new.html.haml模板"&gt;新建&lt;code&gt;users/new.html.haml&lt;/code&gt;模板&lt;/h3&gt;
&lt;p&gt;拷贝&lt;code&gt;ui/signup.html.haml&lt;/code&gt;内容至当前模板&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;expected to find field "name" but there were no matches&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：模板不是实际的内容，没有对应的字段&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑users/new.html.haml模板"&gt;编辑&lt;code&gt;users/new.html.haml&lt;/code&gt;模板&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="s1"&gt;'shared/breadcrumb'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;links: &lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"Home"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#new_user.box&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt; &lt;span class="n"&gt;注册新用户&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form_for&lt;/span&gt; &lt;span class="vi"&gt;@user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;html: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"form-horizontal"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;control&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;
      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;label&lt;/span&gt; &lt;span class="s2"&gt;"用户名"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"control-label"&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;controls&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text_field&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;
      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;label&lt;/span&gt; &lt;span class="s2"&gt;"Email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"control-label"&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;controls&lt;/span&gt;
        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text_field&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;placeholder: &lt;/span&gt;&lt;span class="s2"&gt;"foo@bar.com"&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;submit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;
      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;submit&lt;/span&gt; &lt;span class="s2"&gt;"提交注册信息"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"btn btn-primary"&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#sidebar&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#has_account.box&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt; &lt;span class="n"&gt;已经有帐号了&lt;/span&gt;&lt;span class="err"&gt;？&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"登录"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined methodmodel_name' for NilClass:Class&lt;/code&gt;`&lt;/li&gt;
&lt;li&gt;原因：没有设置&lt;code&gt;@user&lt;/code&gt;变量&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑controllers/users_controller.rb，在new方法中增加对@user4赋值"&gt;编辑&lt;code&gt;controllers/users_controller.rb&lt;/code&gt;，在&lt;code&gt;new&lt;/code&gt;方法中增加对&lt;code&gt;@user&lt;/code&gt;赋值&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;
  &lt;span class="vi"&gt;@user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined methodusers_path' for #&amp;lt;#&amp;lt;Class:0x007fd32d...&lt;/code&gt;`&lt;/li&gt;
&lt;li&gt;原因：没有对&lt;code&gt;users#create&lt;/code&gt;的路由信息&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑config/routes.rb，增加users#create的路由信息"&gt;编辑&lt;code&gt;config/routes.rb&lt;/code&gt;，增加&lt;code&gt;users#create&lt;/code&gt;的路由信息&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:show&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:create&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined methodemail' for #&amp;lt;User id: nil, nam...&lt;/code&gt;`&lt;/li&gt;
&lt;li&gt;原因：&lt;code&gt;user&lt;/code&gt;中没有定义&lt;code&gt;email&lt;/code&gt;字段&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="在rails consle中执行"&gt;在&lt;code&gt;rails consle&lt;/code&gt;中执行&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="s2"&gt;"migration AddEmailToUsers email:string"&lt;/span&gt;
      &lt;span class="n"&gt;invoke&lt;/span&gt;  &lt;span class="n"&gt;active_record&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;migrate&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;20130102003510&lt;/span&gt;&lt;span class="n"&gt;_add_email_to_users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Completed"&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="执行数据库升级"&gt;执行数据库升级&lt;/h3&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake db:migrate
bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake db:test:prepare
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试通过！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="确认用户故事"&gt;确认用户故事&lt;/h2&gt;
&lt;p&gt;###增加测试用例&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# coding: utf-8
feature '访问者希望注册用户' do
  scenario '访问/sign_up, 应该显示注册用页面' do
    visit '/sign_up'

    page.should have_field "user_name"
    page.should have_field "user_email"
  end

  scenario '输入用户名和Email，点击"提交注册信息"按钮，应该显示首页' do
    visit '/sign_up'

    fill_in "user_name", with: "test_user"
    fill_in "user_email", with: "test@test.com"

    click_button "提交注册信息"

    current_path.should == root_path
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;The action 'create' could not be found for UsersController&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有定义&lt;code&gt;create&lt;/code&gt;方法&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑controllers/users_controller.rb，增加create方法"&gt;编辑&lt;code&gt;controllers/users_controller.rb&lt;/code&gt;，增加&lt;code&gt;create&lt;/code&gt;方法&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Missing template users/create, application/create with {:loca...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;create&lt;/code&gt;模板&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑create方法"&gt;编辑&lt;code&gt;create&lt;/code&gt;方法&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;
  &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:user&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="n"&gt;root_path&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Can't mass-assign protected attributes: email&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;email&lt;/code&gt;的属性声明&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑model/user.rb，增加email属性声明"&gt;编辑&lt;code&gt;model/user.rb&lt;/code&gt;，增加&lt;code&gt;email&lt;/code&gt;属性声明&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;attr_accessible&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:email&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试通过！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="完成，提交代码"&gt;完成，提交代码&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit 
git checkout dev
git merge f6 &lt;span class="nt"&gt;--no-ff&lt;/span&gt;
git branch &lt;span class="nt"&gt;-d&lt;/span&gt; f6
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下一步骤：&lt;a href="http://ruby-china.org/topics/7780" title=""&gt;使用 RSpec+Capybara 简单 BDD 入门 -7&lt;/a&gt;&lt;/p&gt;</description>
      <author>blueplanet</author>
      <pubDate>Sat, 05 Jan 2013 21:16:04 +0800</pubDate>
      <link>https://ruby-china.org/topics/7779</link>
      <guid>https://ruby-china.org/topics/7779</guid>
    </item>
    <item>
      <title>使用 RSpec+Capybara 简单 BDD 入门 -5</title>
      <description>&lt;p&gt;目录：&lt;a href="http://ruby-china.org/topics/7770" rel="nofollow" target="_blank"&gt;http://ruby-china.org/topics/7770&lt;/a&gt;
上一步：&lt;a href="http://ruby-china.org/topics/7775" title=""&gt;使用 RSpec+Capybara 简单 BDD 入门 -4&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="用户故事"&gt;用户故事&lt;/h2&gt;
&lt;p&gt;访问者希望看到用户的信息&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;用户名称、创建日期&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="环境准备"&gt;环境准备&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; f5
rails c &lt;span class="c"&gt;# console&lt;/span&gt;
rails s &lt;span class="c"&gt;# server&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="步骤"&gt;步骤&lt;/h2&gt;&lt;h3 id="新建文件spec/features/guest_can_see_user_info_spec.rb"&gt;新建文件&lt;code&gt;spec/features/guest_can_see_user_info_spec.rb&lt;/code&gt;
&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="s1"&gt;'访问者希望看到用户的信息'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'访问/users/:id, 应该显示用户信息'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s2"&gt;"/users/1"&lt;/span&gt;

    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="s2"&gt;"test_user"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;No route matches [GET] "/users/1"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;/users/1&lt;/code&gt;对应的路由信息&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑config/routes.rb，增加路由信息"&gt;编辑&lt;code&gt;config/routes.rb&lt;/code&gt;，增加路由信息&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:show&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;uninitialized constant UsersController&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;UsersController&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="在rails console中执行"&gt;在&lt;code&gt;rails console&lt;/code&gt;中执行&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="s2"&gt;"controller users"&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;  &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;controllers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;users_controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
      &lt;span class="n"&gt;invoke&lt;/span&gt;  &lt;span class="n"&gt;haml&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Completed"&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;The action 'show' could not be found for UsersController&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;show&lt;/code&gt;方法&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑controllers/users_controller，增加show方法"&gt;编辑&lt;code&gt;controllers/users_controller&lt;/code&gt;，增加&lt;code&gt;show&lt;/code&gt;方法&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UsersController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Missing template users/show, application/show with {:loc...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;show&lt;/code&gt;模板&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="新建users/show.html.haml"&gt;新建&lt;code&gt;users/show.html.haml&lt;/code&gt;
&lt;/h3&gt;
&lt;p&gt;拷贝&lt;code&gt;ui/user.html&lt;/code&gt;内容至当前模板&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#user.box&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt; &lt;span class="n"&gt;个人信息&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;gravatar_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'joe@example.com'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;dl&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;span1&lt;/span&gt; &lt;span class="no"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;dd&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;strong&lt;/span&gt; &lt;span class="n"&gt;chucai&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;span1&lt;/span&gt; &lt;span class="no"&gt;Since&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;dd&lt;/span&gt; &lt;span class="mi"&gt;2012&lt;/span&gt;&lt;span class="n"&gt;年2月12日&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;注意：当前用户故事只考虑基本用户信息，最新帖子和最新回复以后的步骤中会增加&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;expected there to be text "test_user" in "社区 会员 knowa...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：页面还是写死的数据&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="修改模板users/show.html.haml"&gt;修改模板&lt;code&gt;users/show.html.haml&lt;/code&gt;
&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#user.box&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt; &lt;span class="n"&gt;个人信息&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;gravatar_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'joe@example.com'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;dl&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;span1&lt;/span&gt; &lt;span class="no"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;dd&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;strong&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@user.name&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;span1&lt;/span&gt; &lt;span class="no"&gt;Since&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;dd&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@user.created_at&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined methodname' for nil:NilClass&lt;/code&gt;`&lt;/li&gt;
&lt;li&gt;原因：没有对&lt;code&gt;@user&lt;/code&gt;变量赋值&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑controllers/users_controller.rb"&gt;编辑&lt;code&gt;controllers/users_controller.rb&lt;/code&gt;
&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UsersController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show&lt;/span&gt;
    &lt;span class="vi"&gt;@user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;uninitialized constant UsersController::User&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;user&lt;/code&gt;这个&lt;code&gt;model&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="在rails console中执行"&gt;在&lt;code&gt;rails console&lt;/code&gt;中执行&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="s2"&gt;"model user name:string"&lt;/span&gt;
      &lt;span class="n"&gt;invoke&lt;/span&gt;  &lt;span class="n"&gt;active_record&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;migrate&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;20130101221838&lt;/span&gt;&lt;span class="n"&gt;_create_users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Completed"&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="执行数据库升级"&gt;执行数据库升级&lt;/h3&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake db:migrate
bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake db:test:prepare
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Couldn't find User with id=1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：测试用例中使用的是写死的数据&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="修改测试用例，增加user部分"&gt;修改测试用例，增加&lt;code&gt;user&lt;/code&gt;部分&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="s1"&gt;'访问者希望看到用户的信息'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="vi"&gt;@user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"test_user"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'访问/users/:id, 应该显示用户信息'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s2"&gt;"/users/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@user.id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@user.name&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@user.created_at.to_s&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试通过！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="完成，提交代码"&gt;完成，提交代码&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit 
git checkout dev
git merge f5 &lt;span class="nt"&gt;--no-ff&lt;/span&gt;
git branch &lt;span class="nt"&gt;-d&lt;/span&gt; f5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下一步骤：&lt;a href="http://ruby-china.org/topics/7779" title=""&gt;使用 RSpec+Capybara 简单 BDD 入门 -6&lt;/a&gt;&lt;/p&gt;</description>
      <author>blueplanet</author>
      <pubDate>Sat, 05 Jan 2013 20:51:36 +0800</pubDate>
      <link>https://ruby-china.org/topics/7776</link>
      <guid>https://ruby-china.org/topics/7776</guid>
    </item>
    <item>
      <title>使用 RSpec+Capybara 简单 BDD 入门 -4</title>
      <description>&lt;p&gt;目录：&lt;a href="http://ruby-china.org/topics/7770" rel="nofollow" target="_blank"&gt;http://ruby-china.org/topics/7770&lt;/a&gt;
上一步：&lt;a href="http://ruby-china.org/topics/7774" title=""&gt;使用 RSpec+Capybara 简单 BDD 入门 -3&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="用户故事"&gt;用户故事&lt;/h2&gt;
&lt;p&gt;访问者希望看到帖子的详细信息&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;显示标题、内容、节点、创建日期&lt;/li&gt;
&lt;li&gt;顶部的导航链接&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="环境准备"&gt;环境准备&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; f4
rails c &lt;span class="c"&gt;# console&lt;/span&gt;
rails s &lt;span class="c"&gt;# server&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="步骤"&gt;步骤&lt;/h2&gt;&lt;h3 id="新建文件spec/features/guest_can_see_topic_info_spec.rb"&gt;新建文件&lt;code&gt;spec/features/guest_can_see_topic_info_spec.rb&lt;/code&gt;
&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="s1"&gt;'访问者希望看到帖子的详细信息'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="vi"&gt;@node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"Ruby"&lt;/span&gt;
    &lt;span class="vi"&gt;@topic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"topic 1 test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="vi"&gt;@node&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'访问/topics/1, 应该显示帖子的详细信息'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s2"&gt;"/topics/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@topic.id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@topic.title&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@topic.node.name&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;No route matches [GET] "/topics/1"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;topics/1&lt;/code&gt;对应的路由信息&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑config/routes.rb，增加topics show的路由设置"&gt;编辑&lt;code&gt;config/routes.rb&lt;/code&gt;，增加&lt;code&gt;topics show&lt;/code&gt;的路由设置&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:topics&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:show&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;The action 'show' could not be found for TopicsController&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：&lt;code&gt;TopicsController&lt;/code&gt;没有定义&lt;code&gt;show&lt;/code&gt;方法&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑controllers/topics_controller.rb，增加show方法定义"&gt;编辑&lt;code&gt;controllers/topics_controller.rb&lt;/code&gt;，增加&lt;code&gt;show&lt;/code&gt;方法定义&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Missing template topics/show, application/show with {:lo...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;show&lt;/code&gt;模板&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="增加topics/show.html.haml，拷贝ui/topic.html.haml的内容至当前模板"&gt;增加&lt;code&gt;topics/show.html.haml&lt;/code&gt;，拷贝&lt;code&gt;ui/topic.html.haml&lt;/code&gt;的内容至当前模板&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;expected there to be text "topic 1 test" in "社区 会...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：模板中是写死的假数据&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="修改topics/show.html.haml内容"&gt;修改&lt;code&gt;topics/show.html.haml&lt;/code&gt;内容&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="s1"&gt;'shared/breadcrumb'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;links: &lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"Home"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"社区"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"新手问题"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"浏览帖子"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#show_topic&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#topic_banner.box.info-box&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@topic.title&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;topic_info&lt;/span&gt;
      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="vi"&gt;@topic.node.name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@topic.node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"  •  "&lt;/span&gt;
      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"knwang"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"user_link"&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"  •  "&lt;/span&gt;
      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"published &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@topic.created_at&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; ago"&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#topic_content.box&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@topic.content&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#sidebar&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#new_topic.box&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"发布新帖"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"btn btn-success"&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#stats.box&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;ul&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt; &lt;span class="n"&gt;社区会员&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4029&lt;/span&gt; &lt;span class="n"&gt;人&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt; &lt;span class="n"&gt;帖子数&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;312&lt;/span&gt; &lt;span class="n"&gt;篇&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt; &lt;span class="n"&gt;回帖数&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3123&lt;/span&gt; &lt;span class="n"&gt;条&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;注意：回复的部分在后面的步骤中做，暂时删掉即可&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined methodtitle' for nil:NilClass&lt;/code&gt;`&lt;/li&gt;
&lt;li&gt;原因：没有对&lt;code&gt;@topic&lt;/code&gt;变量赋值&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑controllers/topics_controller.rb"&gt;编辑&lt;code&gt;controllers/topics_controller.rb&lt;/code&gt;
&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show&lt;/span&gt;
  &lt;span class="vi"&gt;@topic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined methodcontent' for #&amp;lt;Topic:0x0...&lt;/code&gt;`&lt;/li&gt;
&lt;li&gt;原因：最开始生成&lt;code&gt;topic&lt;/code&gt;的时候忘了&lt;code&gt;content&lt;/code&gt;属性了 :)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="在rails console中执行"&gt;在&lt;code&gt;rails console&lt;/code&gt;中执行&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="s2"&gt;"migration AddContentToTopics content:text"&lt;/span&gt;
      &lt;span class="n"&gt;invoke&lt;/span&gt;  &lt;span class="n"&gt;active_record&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;migrate&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;20130101134732&lt;/span&gt;&lt;span class="n"&gt;_add_content_to_topics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Completed"&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="执行数据库升级"&gt;执行数据库升级&lt;/h3&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake db:migrate
bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake db:test:prepare
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试通过！&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="修改测试用例，增加内容和创建时间的验证"&gt;修改测试用例，增加内容和创建时间的验证&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="s1"&gt;'访问者希望看到帖子的详细信息'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="vi"&gt;@node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"Ruby"&lt;/span&gt;
    &lt;span class="vi"&gt;@topic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"topic 1 test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;content: &lt;/span&gt;&lt;span class="s2"&gt;"topic 1 content"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="vi"&gt;@node&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'访问/topics/1, 应该显示帖子的详细信息'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s2"&gt;"/topics/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@topic.id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@topic.title&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@topic.content&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@topic.node.name&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="s2"&gt;"published &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@topic.created_at&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; ago"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Can't mass-assign protected attributes: content&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有设置&lt;code&gt;content&lt;/code&gt;的访问属性&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑model/topic.rb"&gt;编辑&lt;code&gt;model/topic.rb&lt;/code&gt;
&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;attr_accessible&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:content&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试通过！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="再次确认用户故事"&gt;再次确认用户故事&lt;/h2&gt;&lt;h3 id="增加导航栏的验证"&gt;增加导航栏的验证&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_link&lt;/span&gt; &lt;span class="s2"&gt;"Home"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;href: &lt;/span&gt;&lt;span class="n"&gt;root_path&lt;/span&gt;
&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_link&lt;/span&gt; &lt;span class="vi"&gt;@topic.node.name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;href: &lt;/span&gt;&lt;span class="n"&gt;node_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@topic.node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_link&lt;/span&gt; &lt;span class="s2"&gt;"浏览帖子"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;href: &lt;/span&gt;&lt;span class="n"&gt;topic_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@topic&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined local variable or methodroot_path' for...&lt;/code&gt;`n&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;root_path&lt;/code&gt;的定义&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑config/routes.rb，增加root_path的定义"&gt;编辑&lt;code&gt;config/routes.rb&lt;/code&gt;，增加&lt;code&gt;root_path&lt;/code&gt;的定义&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;MyRubyChina&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;draw&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:topics&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:show&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:nodes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:show&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s2"&gt;"topics#index"&lt;/span&gt;

  &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="s1"&gt;'ui/:action'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;controller: &lt;/span&gt;&lt;span class="s1"&gt;'ui'&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="删除默认的主页文件"&gt;删除默认的主页文件&lt;/h4&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;rm &lt;/span&gt;public/index.html
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;expected to find link "Home" but there were no matches. Als...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有定义对应的链接&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑topics/show.html.haml，修改顶部导航栏链接"&gt;编辑&lt;code&gt;topics/show.html.haml&lt;/code&gt;，修改顶部导航栏链接&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="s1"&gt;'shared/breadcrumb'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;links: &lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"Home"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;root_path&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="vi"&gt;@topic.node.name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@topic.node&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"浏览帖子"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@topic&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试通过！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="完成，提交代码"&gt;完成，提交代码&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git &lt;span class="nb"&gt;rm &lt;/span&gt;public/index.html
git commit 
git checkout dev
git merge f4 &lt;span class="nt"&gt;--no-ff&lt;/span&gt;
git branch &lt;span class="nt"&gt;-d&lt;/span&gt; f4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下一步骤：&lt;a href="http://ruby-china.org/topics/7776" title=""&gt;使用 RSpec+Capybara 简单 BDD 入门 -5&lt;/a&gt;&lt;/p&gt;</description>
      <author>blueplanet</author>
      <pubDate>Sat, 05 Jan 2013 20:40:48 +0800</pubDate>
      <link>https://ruby-china.org/topics/7775</link>
      <guid>https://ruby-china.org/topics/7775</guid>
    </item>
    <item>
      <title>使用 RSpec+Capybara 简单 BDD 入门 -3</title>
      <description>&lt;p&gt;目录：&lt;a href="http://ruby-china.org/topics/7770" rel="nofollow" target="_blank"&gt;http://ruby-china.org/topics/7770&lt;/a&gt;
上一步：&lt;a href="http://ruby-china.org/topics/7773" title=""&gt;使用 RSpec+Capybara 简单 BDD 入门 -2&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="用户故事"&gt;用户故事&lt;/h2&gt;
&lt;p&gt;访问者希望看到一个节点的帖子列表&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;点击节点后显示该节点的帖子列表&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="环境准备"&gt;环境准备&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; f3
rails c &lt;span class="c"&gt;# console&lt;/span&gt;
rails s &lt;span class="c"&gt;# server&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="步骤"&gt;步骤&lt;/h2&gt;&lt;h3 id="新建文件spec/features/nodes_spec.rb"&gt;新建文件&lt;code&gt;spec/features/nodes_spec.rb&lt;/code&gt;
&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="s1"&gt;'访问者希望看到一个节点的帖子列表'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="vi"&gt;@node1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"Ruby Node"&lt;/span&gt;
    &lt;span class="vi"&gt;@node2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"Rails Node"&lt;/span&gt;

    &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_index&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"topic &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="vi"&gt;@node1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_index&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"topic &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="vi"&gt;@node2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'点击节点名称后，应该显示该节点的帖子列表'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s1"&gt;'/topics'&lt;/span&gt;

    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@node1.name&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@node2.name&lt;/span&gt;

    &lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@node1.name&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;

    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@node1.name&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should_not&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@node2.name&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Failure/Error: page.should_not have_content @node2.name expected there not to be text "Rails Node" in "....&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：节点的链接还是无效链接，没有起作用&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="修改topics/index.html.haml"&gt;修改&lt;code&gt;topics/index.html.haml&lt;/code&gt;
&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;修改为&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined method node_path' for ...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有定义&lt;code&gt;node&lt;/code&gt;的路由信息&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="修改config/routes.rb，增加node的路由定义"&gt;修改&lt;code&gt;config/routes.rb&lt;/code&gt;，增加&lt;code&gt;node&lt;/code&gt;的路由定义&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:nodes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:show&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;uninitialized constant NodesController&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有 node controller&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="在rails console中执行"&gt;在&lt;code&gt;rails console&lt;/code&gt;中执行&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="s2"&gt;"controller nodes"&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;  &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;controllers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nodes_controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
      &lt;span class="n"&gt;invoke&lt;/span&gt;  &lt;span class="n"&gt;haml&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;nodes&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Completed"&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;The action 'show' could not be found for NodesController&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;show&lt;/code&gt;方法&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑controllers/nodes_controller.rb，增加show方法"&gt;编辑&lt;code&gt;controllers/nodes_controller.rb&lt;/code&gt;，增加&lt;code&gt;show&lt;/code&gt;方法&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NodesController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Missing template nodes/show, application/show with {:...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;show&lt;/code&gt;模板&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="新建views/nodes/show.html.haml"&gt;新建&lt;code&gt;views/nodes/show.html.haml&lt;/code&gt;
&lt;/h3&gt;
&lt;p&gt;拷贝&lt;code&gt;ui/node.html&lt;/code&gt;至上述文件，并修改第 5 行&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined methodname' for nil:NilClass&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有对&lt;code&gt;@node&lt;/code&gt;赋值&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑controllers/nodes_controller.rb，增加@user12的赋值"&gt;编辑&lt;code&gt;controllers/nodes_controller.rb&lt;/code&gt;，增加&lt;code&gt;@node&lt;/code&gt;的赋值&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="vi"&gt;@node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试成功！但只是因为都是写死的数据，所以需要继续修改&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="修改nodes/show.html.haml第7行"&gt;修改&lt;code&gt;nodes/show.html.haml&lt;/code&gt;第 7 行&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@node.description&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined methoddescription' for #&amp;lt;...&lt;/code&gt;`&lt;/li&gt;
&lt;li&gt;原因：&lt;code&gt;node&lt;/code&gt;没有&lt;code&gt;description&lt;/code&gt;方法&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="在rails console中执行"&gt;在&lt;code&gt;rails console&lt;/code&gt;中执行&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="s2"&gt;"migration AddDescriptionToNodes description:text"&lt;/span&gt;
      &lt;span class="n"&gt;invoke&lt;/span&gt;  &lt;span class="n"&gt;active_record&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;migrate&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;20130101042100&lt;/span&gt;&lt;span class="n"&gt;_add_description_to_nodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Completed"&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="执行数据库升级"&gt;执行数据库升级&lt;/h3&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake db:migrate
bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake db:test:prepare
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试成功。但各个帖子的信息还是写死的数据&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑controllers/nodes_controller.rb，修改帖子列表的部分"&gt;编辑&lt;code&gt;controllers/nodes_controller.rb&lt;/code&gt;，修改帖子列表的部分&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="s1"&gt;'shared/breadcrumb'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;links: &lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"Home"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"社区"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Ruby"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#node_topics&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#node_info.box.box-gray.info-box&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@node.name&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="n"&gt;共有48个讨论主题&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@node.description&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;topics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="vi"&gt;@node.topics.each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;span1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;gravatar_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'joe@example.com'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;span7&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;topic_title&lt;/span&gt;
            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;topic_info&lt;/span&gt;
            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;
            &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"  •  "&lt;/span&gt;
            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"knwang"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"user_link"&lt;/span&gt;
            &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"  •  "&lt;/span&gt;
            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"published &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;time_ago_in_words&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; ago"&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;span1&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#sidebar&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#new_topic.box&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"发布新帖"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"btn btn-success"&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#stats.box&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;ul&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt; &lt;span class="n"&gt;社区会员&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4029&lt;/span&gt; &lt;span class="n"&gt;人&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt; &lt;span class="n"&gt;帖子数&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;312&lt;/span&gt; &lt;span class="n"&gt;篇&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt; &lt;span class="n"&gt;回帖数&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3123&lt;/span&gt; &lt;span class="n"&gt;条&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined methodtopics' for #&amp;lt;Node:...&lt;/code&gt;`&lt;/li&gt;
&lt;li&gt;原因：&lt;code&gt;node&lt;/code&gt;没有&lt;code&gt;topics&lt;/code&gt;方法&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑model/node.rb，增加topics的声明"&gt;编辑&lt;code&gt;model/node.rb&lt;/code&gt;，增加&lt;code&gt;topics&lt;/code&gt;的声明&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:topics&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;测试成功！&lt;/p&gt;
&lt;h2 id="重构"&gt;重构&lt;/h2&gt;
&lt;p&gt;仔细看一下，&lt;code&gt;topics/index.html.haml&lt;/code&gt;和&lt;code&gt;nodes/show.html.haml&lt;/code&gt;两个页面中，显示帖子列表的部分是完全相同的，可以提出一个部分模板&lt;/p&gt;
&lt;h3 id="新建topics/_topics.html.haml"&gt;新建&lt;code&gt;topics/_topics.html.haml&lt;/code&gt;
&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;%ul.topics.box
  - topics.each do |topic|
    %li
      %a.span1(href="")
        %img(src="#{gravatar_url('joe@example.com')}")
      %article.span7
        %p.topic_title
          = link_to topic.title
        %p.topic_info
          = link_to topic.node.name, topic.node, class: "node"
          %span= "  â€˘  "
          = link_to "knwang", nil, class: "user_link"
          %span= "  â€˘  "
          = "published #{time_ago_in_words(topic.created_at)} ago"
      %p.replies.span1
        %span 12
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;** 注意：把&lt;code&gt;@topics&lt;/code&gt;变量修改为本地变量&lt;code&gt;topics&lt;/code&gt;**&lt;/p&gt;
&lt;h3 id="修改topics/index.html.haml"&gt;修改&lt;code&gt;topics/index.html.haml&lt;/code&gt;
&lt;/h3&gt;
&lt;p&gt;把文件中上述部分删除后，增加部分模板的调用&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="n"&gt;查看&lt;/span&gt;&lt;span class="err"&gt;：&lt;/span&gt; &lt;span class="n"&gt;默认&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="s1"&gt;'topics'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;topics: &lt;/span&gt;&lt;span class="vi"&gt;@topics&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#sidebar&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#new_topic.box&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="修改nodex/show.html.haml"&gt;修改 nodex/show.html.haml&lt;/h3&gt;
&lt;p&gt;把文件中上述部分删除后，增加部分模板的调用&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="n"&gt;共有48个讨论主题&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@node.description&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="s1"&gt;'topics/topics'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;topics: &lt;/span&gt;&lt;span class="vi"&gt;@node.topics&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#sidebar&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#new_topic.box&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;注意：传入变量的部分略有不同&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;测试应该正常全部通过&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="完善spec"&gt;完善 spec&lt;/h2&gt;&lt;h3 id="编辑spec/features/nodes_spec.rb，增加description的设置以及验证"&gt;编辑&lt;code&gt;spec/features/nodes_spec.rb&lt;/code&gt;，增加&lt;code&gt;description&lt;/code&gt;的设置以及验证&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="s1"&gt;'访问者希望看到一个节点的帖子列表'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="vi"&gt;@node1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"Ruby Node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;description: &lt;/span&gt;&lt;span class="s2"&gt;"Ruby是一门优美的语言"&lt;/span&gt;
    &lt;span class="vi"&gt;@node2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"Rails Node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;description: &lt;/span&gt;&lt;span class="s2"&gt;"Rails是一个快速WEB开发框架"&lt;/span&gt;

    &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_index&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"topic &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="vi"&gt;@node1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_index&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"topic &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="vi"&gt;@node2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'点击节点名称后，应该显示该节点的帖子列表'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s1"&gt;'/topics'&lt;/span&gt;

    &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@node1.name&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;

    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@node1.name&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@node1.description&lt;/span&gt;

    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should_not&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@node2.name&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should_not&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="vi"&gt;@node2.description&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Can't mass-assign protected attributes: description&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：&lt;code&gt;description&lt;/code&gt;的访问属性没有设置&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;好险，这个地方忘记了！&lt;/p&gt;
&lt;h3 id="编辑model/node.rb，增加description属性声明"&gt;编辑&lt;code&gt;model/node.rb&lt;/code&gt;，增加&lt;code&gt;description&lt;/code&gt;属性声明&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;attr_accessible&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:description&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试通过！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="完成，提交代码"&gt;完成，提交代码&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit 
git checkout dev
git merge f3 &lt;span class="nt"&gt;--no-ff&lt;/span&gt;
git branch &lt;span class="nt"&gt;-d&lt;/span&gt; f3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下一步骤：&lt;a href="http://ruby-china.org/topics/7775" title=""&gt;使用 RSpec+Capybara 简单 BDD 入门 -4&lt;/a&gt;&lt;/p&gt;</description>
      <author>blueplanet</author>
      <pubDate>Sat, 05 Jan 2013 20:29:07 +0800</pubDate>
      <link>https://ruby-china.org/topics/7774</link>
      <guid>https://ruby-china.org/topics/7774</guid>
    </item>
    <item>
      <title>使用 RSpec+Capybara 简单 BDD 入门 -2</title>
      <description>&lt;p&gt;目录：&lt;a href="http://ruby-china.org/topics/7770" rel="nofollow" target="_blank"&gt;http://ruby-china.org/topics/7770&lt;/a&gt;
上一步：&lt;a href="http://ruby-china.org/topics/7771" title=""&gt;使用 RSpec+Capybara 简单 BDD 入门 -1&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="用户故事"&gt;用户故事&lt;/h2&gt;
&lt;p&gt;访问者希望看到帖子的节点&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;在帖子列表中显示帖子名称&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="环境准备"&gt;环境准备&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; f2
rails c &lt;span class="c"&gt;# console&lt;/span&gt;
rails s &lt;span class="c"&gt;# server&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="步骤"&gt;步骤&lt;/h2&gt;&lt;h3 id="新建文件spec/features/guest_can_see_node_name_spec.rb"&gt;新建文件&lt;code&gt;spec/features/guest_can_see_node_name_spec.rb&lt;/code&gt;
&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="s1"&gt;'访问者希望看到帖子的节点名称'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete_all&lt;/span&gt;

    &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"DHH 的公开课"&lt;/span&gt;
    &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"Rails3 中 compass 的 IE 使用问题"&lt;/span&gt;
    &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"这周二上海搞Ruby Tuesday么？"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s1"&gt;'/topics'&lt;/span&gt;

    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="s1"&gt;'瞎扯淡'&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;expected there to be text "瞎扯淡" in "社区 会员 knowan...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：还没有实现的代码&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑topics/index.html.haml"&gt;编辑 topics/index.html.haml&lt;/h3&gt;
&lt;p&gt;把这一行&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"分享"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;修改为&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined methodnode' for #Topic:0x007fa4bc0d96d0&lt;/code&gt;`&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;node&lt;/code&gt;这个方法&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑model/topic.rb"&gt;编辑&lt;code&gt;model/topic.rb&lt;/code&gt;
&lt;/h3&gt;
&lt;p&gt;增加&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:node&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined methodname' for nil:NilClass&lt;/code&gt;`&lt;/li&gt;
&lt;li&gt;原因：&lt;code&gt;node&lt;/code&gt;没有值&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="生成Node这个model，在rails console中执行"&gt;生成&lt;code&gt;Node&lt;/code&gt;这个&lt;code&gt;model&lt;/code&gt;，在&lt;code&gt;rails console&lt;/code&gt;中执行&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="s2"&gt;"model node name:string"&lt;/span&gt;
      &lt;span class="n"&gt;invoke&lt;/span&gt;  &lt;span class="n"&gt;active_record&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;migrate&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;20121231023808&lt;/span&gt;&lt;span class="n"&gt;_create_nodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Completed"&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="增加node_id。在rails console中执行"&gt;增加&lt;code&gt;node_id&lt;/code&gt;。在&lt;code&gt;rails console&lt;/code&gt;中执行&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="s2"&gt;"migration AddNodeIdToTopics node_id:integer"&lt;/span&gt;
      &lt;span class="n"&gt;invoke&lt;/span&gt;  &lt;span class="n"&gt;active_record&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;migrate&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;20121231030435&lt;/span&gt;&lt;span class="n"&gt;_add_node_id_to_topics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Completed"&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="执行数据库升级"&gt;执行数据库升级&lt;/h3&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake db:migrate
bundle &lt;span class="nb"&gt;exec &lt;/span&gt;rake db:test:prepare
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="修改测试用例"&gt;修改测试用例&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="s1"&gt;'访问者希望看到帖子的节点名称'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete_all&lt;/span&gt;
    &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete_all&lt;/span&gt;

    &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"瞎扯淡"&lt;/span&gt;

    &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"DHH 的公开课"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;
    &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"Rails3 中 compass 的 IE 使用问题"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;
    &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"这周二上海搞Ruby Tuesday么？"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'访问/topics, 应该显示所有帖子的节点名称'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s1"&gt;'/topics'&lt;/span&gt;

    &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Can't mass-assign protected attributes: node&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有对&lt;code&gt;node&lt;/code&gt;设置访问属性&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="修改model/node.rb，增加node的属性声明"&gt;修改&lt;code&gt;model/node.rb&lt;/code&gt;，增加&lt;code&gt;node&lt;/code&gt;的属性声明&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;attr_accessible&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:node&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;当前测试成功，但前一个测试失败&lt;/li&gt;
&lt;li&gt;原因：前一个测试用例中没有设置&lt;code&gt;node&lt;/code&gt;信息&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="修改测试用例spec/features/guest_can_see_all_topics_spec.rb，增加Node的赋值"&gt;修改测试用例&lt;code&gt;spec/features/guest_can_see_all_topics_spec.rb&lt;/code&gt;，增加&lt;code&gt;Node&lt;/code&gt;的赋值&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete_all&lt;/span&gt;

&lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s2"&gt;"瞎扯淡"&lt;/span&gt;

&lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"DHH 的公开课"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;
&lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"Rails3 中 compass 的 IE 使用问题"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;
&lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"这周二上海搞Ruby Tuesday么？"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;node: &lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试全部通过&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="提交代码"&gt;提交代码&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit 
git checkout dev
git merge f2 &lt;span class="nt"&gt;--no-ff&lt;/span&gt;
git branch &lt;span class="nt"&gt;-d&lt;/span&gt; f2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下一步骤：&lt;a href="http://ruby-china.org/topics/7774" title=""&gt;使用 RSpec+Capybara 简单 BDD 入门 -3&lt;/a&gt;&lt;/p&gt;</description>
      <author>blueplanet</author>
      <pubDate>Sat, 05 Jan 2013 20:18:13 +0800</pubDate>
      <link>https://ruby-china.org/topics/7773</link>
      <guid>https://ruby-china.org/topics/7773</guid>
    </item>
    <item>
      <title>使用 RSpec+Capybara 简单 BDD 入门 -1</title>
      <description>&lt;p&gt;&lt;a href="http://ruby-china.org/topics/7770" title=""&gt;目录&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="用户故事"&gt;用户故事&lt;/h2&gt;
&lt;p&gt;访问者希望看到所有帖子的列表&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;显示帖子的标题和创建时间&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="环境准备"&gt;环境准备&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; f1
rails c &lt;span class="c"&gt;# console&lt;/span&gt;
rails s &lt;span class="c"&gt;# server&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="步骤"&gt;步骤&lt;/h2&gt;&lt;h3 id="新建文件spec/features/guest_can_see_all_topics_spec.rb"&gt;新建文件&lt;code&gt;spec/features/guest_can_see_all_topics_spec.rb&lt;/code&gt;
&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="s1"&gt;'访问者希望看到所有帖子的列表'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'访问/topics, 应该显示所有帖子'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s1"&gt;'/topics'&lt;/span&gt;

    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="s2"&gt;"DHH 的公开课"&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="s2"&gt;"Rails3 中 compass 的 IE 使用问题"&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="s2"&gt;"这周二上海搞Ruby Tuesday么？"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：No route matches [GET] "/topics"&lt;/li&gt;
&lt;li&gt;原因：没有正确的路由设置信息&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑config/route.rb, 增加topics的定义"&gt;编辑&lt;code&gt;config/route.rb&lt;/code&gt;, 增加&lt;code&gt;topics&lt;/code&gt;的定义&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:topics&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;only: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;uninitialized constant TopicsController&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有定义&lt;code&gt;TopicsController&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="在rails console中执行"&gt;在&lt;code&gt;rails console&lt;/code&gt;中执行&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="s2"&gt;"controller topics"&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;  &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;controllers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;topics_controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
      &lt;span class="n"&gt;invoke&lt;/span&gt;  &lt;span class="n"&gt;haml&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;topics&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Completed"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;The action 'index' could not be found for TopicsController&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：&lt;code&gt;TopicsController&lt;/code&gt;中没有定义&lt;code&gt;index&lt;/code&gt;方法&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑 topics_controller.rb"&gt;编辑 &lt;code&gt;topics_controller.rb&lt;/code&gt;
&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TopicsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Missing template topics/index, application/index ...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有&lt;code&gt;topics/index&lt;/code&gt;模板&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="新建文件：app/views/topics/index.html.haml"&gt;新建文件：&lt;code&gt;app/views/topics/index.html.haml&lt;/code&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;Failure/Error: page.should have_content "DHH 的公开课"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：模板中没有显示内容&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;拷贝&lt;code&gt;ui/topics.html.haml&lt;/code&gt;的内容至当前模板&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;测试成功了，但是不要高兴！成功是因为页面上所有的数据都是写死的假数据。必须更改为正确的代码&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑app/views/topics/index.html.haml"&gt;编辑&lt;code&gt;app/views/topics/index.html.haml&lt;/code&gt;
&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="s1"&gt;'shared/breadcrumb'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;links: &lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s2"&gt;"Home"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"社区"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#topics&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#topics_info.box.box-gray.info-box&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="n"&gt;查看&lt;/span&gt;&lt;span class="err"&gt;：&lt;/span&gt; &lt;span class="n"&gt;默认&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;topics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="vi"&gt;@topics.each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;span1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;gravatar_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'joe@example.com'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;span7&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;topic_title&lt;/span&gt;
            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;topic_info&lt;/span&gt;
            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"分享"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;
            &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"  •  "&lt;/span&gt;
            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"knwang"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"user_link"&lt;/span&gt;
            &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"  •  "&lt;/span&gt;
            &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"published &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;time_ago_in_words&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; ago"&lt;/span&gt;
        &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;span1&lt;/span&gt;
          &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;

&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#sidebar&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#new_topic.box&lt;/span&gt;
    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"发布新帖"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"btn btn-success"&lt;/span&gt;
  &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="c1"&gt;#stats.box&lt;/span&gt;
    &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;ul&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt; &lt;span class="n"&gt;社区会员&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4029&lt;/span&gt; &lt;span class="n"&gt;人&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt; &lt;span class="n"&gt;帖子数&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;312&lt;/span&gt; &lt;span class="n"&gt;篇&lt;/span&gt;
      &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt; &lt;span class="n"&gt;回帖数&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3123&lt;/span&gt; &lt;span class="n"&gt;条&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;undefined methodeach' for nil:NilClass&lt;/code&gt;`&lt;/li&gt;
&lt;li&gt;原因：&lt;code&gt;TopicsController&lt;/code&gt;的&lt;code&gt;index&lt;/code&gt;方法中没有对&lt;code&gt;@topics&lt;/code&gt;赋值&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑topics_controller.rb，增加赋值部分"&gt;编辑&lt;code&gt;topics_controller.rb&lt;/code&gt;，增加赋值部分&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TopicsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
    &lt;span class="vi"&gt;@topics&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;注意：由于是示范项目所以直接使用了 Topic.all，实际项目中绝对不能这样做&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;uninitialized constant TopicsController::Topic&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：没有 &lt;code&gt;Topic&lt;/code&gt; 这个 &lt;code&gt;model&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="在rails conssole中执行"&gt;在&lt;code&gt;rails conssole&lt;/code&gt;中执行&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt; &lt;span class="s2"&gt;"model topic title"&lt;/span&gt;
      &lt;span class="n"&gt;invoke&lt;/span&gt;  &lt;span class="n"&gt;active_record&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;migrate&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;20121229122838&lt;/span&gt;&lt;span class="n"&gt;_create_topics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
      &lt;span class="n"&gt;create&lt;/span&gt;    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Completed"&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;pry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试失败：&lt;code&gt;expected there to be text "DHH 的公开课" in "社区...&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;原因：测试数据库中没有对应的数据&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="编辑 spec/features/guest_can_see_all_topics_spec.rb，增加background部分"&gt;编辑 &lt;code&gt;spec/features/guest_can_see_all_topics_spec.rb&lt;/code&gt;，增加&lt;code&gt;background&lt;/code&gt;部分&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="s1"&gt;'访问者希望看到所有帖子的列表'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete_all&lt;/span&gt;

    &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"DHH 的公开课"&lt;/span&gt;
    &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"Rails3 中 compass 的 IE 使用问题"&lt;/span&gt;
    &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt; &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s2"&gt;"这周二上海搞Ruby Tuesday么？"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;scenario&lt;/span&gt; &lt;span class="s1"&gt;'访问/topics, 应该显示所有帖子'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;visit&lt;/span&gt; &lt;span class="s1"&gt;'/topics'&lt;/span&gt;

    &lt;span class="no"&gt;Topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;have_content&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;测试成功！！完成！！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="提交代码"&gt;提交代码&lt;/h2&gt;
&lt;p&gt;git add .
git commit
git checkout dev
git merge f1 --no-ff
git push origin dev&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;执行测试之后，按照提示的错误进行修改即可&lt;/li&gt;
&lt;li&gt;问题

&lt;ul&gt;
&lt;li&gt;目前自动测试基本不起作用，每次都需要手动执行测试&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;下一步骤：&lt;a href="http://ruby-china.org/topics/7773" title=""&gt;使用 RSpec+Capybara 简单 BDD 入门 -2&lt;/a&gt;&lt;/p&gt;</description>
      <author>blueplanet</author>
      <pubDate>Sat, 05 Jan 2013 20:09:34 +0800</pubDate>
      <link>https://ruby-china.org/topics/7771</link>
      <guid>https://ruby-china.org/topics/7771</guid>
    </item>
    <item>
      <title>使用 RSpec + Capybara 简单 BDD 入门 -目录</title>
      <description>&lt;h2 id="前提"&gt;前提&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;我也是个 Rails 初学者，文中可能会有考虑不周或者错误的地方，希望大家多指正，共同进步&lt;/li&gt;
&lt;li&gt;计划是使用 RSpec+Capybara 写 features 测试＋简单的单元测试，并不是完全的 BDD，是一个简略版本&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="缘起"&gt;缘起&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;前段时间刚看完了 The RSpec Book 之后对 BDD 特别感兴趣，尝试了一下 cucumber 但不是很顺利就暂时放下了&lt;/li&gt;
&lt;li&gt;之后有幸参加了的社区最高楼 &lt;a href="/knwang" class="user-mention" title="@knwang"&gt;&lt;i&gt;@&lt;/i&gt;knwang&lt;/a&gt; 周四晚现场编程网上演示 面向新手的现场演示，被从外至内的理念震撼了 &lt;a href="http://railscasts-china.com/episodes/kevin-open-class" rel="nofollow" target="_blank" title=""&gt;视频在这里&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="/knwang" class="user-mention" title="@knwang"&gt;&lt;i&gt;@&lt;/i&gt;knwang&lt;/a&gt; 在交流时间里说过，实际项目开发的时候，会使用 TDD/BDD 进行开发，但基本的从外至内的理念是不变的，于是参加活动之后，先是按照 &lt;a href="/knwang" class="user-mention" title="@knwang"&gt;&lt;i&gt;@&lt;/i&gt;knwang&lt;/a&gt; 的演示步骤自己动手做了几遍，觉得收获非常大，如果能够把 RSpec 加进去的话应该更完美。&lt;/li&gt;
&lt;li&gt;最近又学到了 RSpec 写 features 的方法，于是决定使用 RSpec+Capybara 来把 &lt;a href="/knwang" class="user-mention" title="@knwang"&gt;&lt;i&gt;@&lt;/i&gt;knwang&lt;/a&gt; 的步骤重新做一遍，顺便把这个过程记录下来，希望能够对其他人有所帮助&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="计划"&gt;计划&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;完全按照 &lt;a href="/knwang" class="user-mention" title="@knwang"&gt;&lt;i&gt;@&lt;/i&gt;knwang&lt;/a&gt; 的步骤，重写一遍 Ruby China Clone&lt;/li&gt;
&lt;li&gt;使用 RSpec+Capybara 编写测试&lt;/li&gt;
&lt;li&gt;每个步骤新开一个帖子，这个帖子作为目录。步骤完成后把新帖子链接加到这个帖子里&lt;/li&gt;
&lt;li&gt;把 &lt;a href="/knwang" class="user-mention" title="@knwang"&gt;&lt;i&gt;@&lt;/i&gt;knwang&lt;/a&gt; 的步骤翻译成了中文。由于英文水平很低，并且用户故事的写法也不是很熟练，可能看起来比较生硬，请见谅&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="步骤"&gt;步骤&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://ruby-china.org/topics/7771" title=""&gt;访问者希望看到所有帖子的列表&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ruby-china.org/topics/7773" title=""&gt;访问者希望看到帖子的节点&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ruby-china.org/topics/7774" title=""&gt;访问者希望看到一个节点的帖子列表&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ruby-china.org/topics/7775" title=""&gt;访问者希望看到帖子的详细信息&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ruby-china.org/topics/7776" title=""&gt;访问者希望看到用户的信息&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ruby-china.org/topics/7779" title=""&gt;访问者希望注册用户&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ruby-china.org/topics/7780" title=""&gt;访问者希望登录&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ruby-china.org/topics/7781" title=""&gt;用户希望发布新帖&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ruby-china.org/topics/7782" title=""&gt;用户希望看到帖子的回复列表&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ruby-china.org/topics/7785" title=""&gt;用户希望看到最新回复的信息&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ruby-china.org/topics/7787" title=""&gt;用户希望对帖子进行回复&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="可能出现的问题"&gt;可能出现的问题&lt;/h2&gt;&lt;h3 id="无法退出。按照下面的步骤实现即可"&gt;无法退出。按照下面的步骤实现即可&lt;/h3&gt;&lt;h4 id="编辑controllers/sessions_controller.rb，增加destroy方法"&gt;编辑&lt;code&gt;controllers/sessions_controller.rb&lt;/code&gt;，增加&lt;code&gt;destroy&lt;/code&gt;方法&lt;/h4&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;destroy&lt;/span&gt;
  &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:user_name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
  &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="n"&gt;root_path&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="编辑layouts/application.html.haml，修改第26行的链接"&gt;编辑&lt;code&gt;layouts/application.html.haml&lt;/code&gt;，修改第 26 行的链接&lt;/h4&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;link_to&lt;/span&gt; &lt;span class="s2"&gt;"退出"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sign_out_path&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="编辑conf/routes.rb，增加路由信息"&gt;编辑&lt;code&gt;conf/routes.rb&lt;/code&gt;，增加路由信息&lt;/h4&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="s1"&gt;'sign_out'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s2"&gt;"sessions#destroy"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="在使用rails server后启动浏览器进行测试的时候没有Node"&gt;在使用&lt;code&gt;rails server&lt;/code&gt;后启动浏览器进行测试的时候没有&lt;code&gt;Node&lt;/code&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;由于是示范项目，所以并没有把所有功能做完&lt;/li&gt;
&lt;li&gt;可以在&lt;code&gt;rails console&lt;/code&gt;里面加上几个就可以了&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="起步"&gt;起步&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;参考我的 git 库

&lt;ul&gt;
&lt;li&gt;gitcafe : &lt;a href="https://gitcafe.com/blueplanet/ruby_china_clone" rel="nofollow" target="_blank"&gt;https://gitcafe.com/blueplanet/ruby_china_clone&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;github : &lt;a href="https://github.com/blueplanet/ruby_china_clone" rel="nofollow" target="_blank"&gt;https://github.com/blueplanet/ruby_china_clone&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;主要有两个分支：

&lt;ul&gt;
&lt;li&gt;master 分支：从 &lt;a href="/knwang" class="user-mention" title="@knwang"&gt;&lt;i&gt;@&lt;/i&gt;knwang&lt;/a&gt; 的库拷贝过来的。除了基本的框架之外还有 ui 这个 controller。相当于美工做好的设计，纯 HTML 加上假的数据。这个分支不打算更新&lt;/li&gt;
&lt;li&gt;dev 分支：今后的开发分支。修改会提交到这个分支&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="本地开发步骤"&gt;本地开发步骤&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://gitcafe.com/blueplanet/ruby_china_clone.git
&lt;span class="nb"&gt;cd &lt;/span&gt;ruby_china_clone
git checkout master
git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; dev &lt;span class="c"&gt;# 创建dev分支&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;启动自动测试环境&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bundle &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--without&lt;/span&gt; production &lt;span class="c"&gt;# 只安装开发环境和测试环境需要的gem&lt;/span&gt;
bundle &lt;span class="nb"&gt;exec &lt;/span&gt;guard
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;执行之后如果出现下面的提示，说明环境没问题了&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Finished &lt;span class="k"&gt;in &lt;/span&gt;0.00856 seconds 
0 examples, 0 failures           
Randomized with seed 26104    
Done.  
17:00:57 - INFO - Guard is now watching at ....
&lt;span class="o"&gt;[&lt;/span&gt;1] guard&lt;span class="o"&gt;(&lt;/span&gt;main&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以后的步骤中，新建或者保存 spec 文件之后，会自动执行对应的测试&lt;/p&gt;

&lt;p&gt;先把坑挖好，慢慢填上！&lt;/p&gt;
&lt;h2 id="感想"&gt;感想&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;真正动手很重要

&lt;ul&gt;
&lt;li&gt;实际花费时间：写帖子 20 小时左右，之前的练习和调查也至少是这个数字&lt;/li&gt;
&lt;li&gt;这 40 个小时，感觉是进步最大最快的 40 个小时。所以，不能只顾看书，动手才是真的！&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;实际开发很复杂

&lt;ul&gt;
&lt;li&gt;由于示范的侧重点不同，实际上回避了两个比较大的问题。一是 UI 设计，二是用户故事的写法。&lt;/li&gt;
&lt;li&gt;实际上如果自己做项目，最先遇到的就是这两个问题。至少我是撞得够呛，呵呵。计划下个阶段摸索一下这两个方面。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;最后，再次感谢 &lt;a href="/knwang" class="user-mention" title="@knwang"&gt;&lt;i&gt;@&lt;/i&gt;knwang&lt;/a&gt; 的演示！&lt;/p&gt;</description>
      <author>blueplanet</author>
      <pubDate>Sat, 05 Jan 2013 20:01:01 +0800</pubDate>
      <link>https://ruby-china.org/topics/7770</link>
      <guid>https://ruby-china.org/topics/7770</guid>
    </item>
    <item>
      <title>开发模式启动 rails server 后，貌似 CSS 没起作用</title>
      <description>&lt;p&gt;我是 Rails 初学者，遇到的问题如题，
执行&lt;code&gt;setup.rb&lt;/code&gt;正常结束后，执行&lt;code&gt;rails server&lt;/code&gt;启动进程也成功。
打开 3000 端口结果是这个样子，貌似 CSS 没起作用。
不知道是哪儿的问题呢？&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;操作系统：MacOS 10.8&lt;/li&gt;
&lt;li&gt;Ruby: 1.9.3p194&lt;/li&gt;
&lt;li&gt;MongoDB: 2.2.0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;效果图：
&lt;img src="//l.ruby-china.com/photo/7d042ed4f90763dc8dcf23efc15734aa.png" title="" alt="效果图"&gt;&lt;/p&gt;</description>
      <author>blueplanet</author>
      <pubDate>Wed, 19 Sep 2012 06:29:15 +0800</pubDate>
      <link>https://ruby-china.org/topics/5623</link>
      <guid>https://ruby-china.org/topics/5623</guid>
    </item>
  </channel>
</rss>
