Basic TDD in Rails : Create a New Article Feature

Objective


  • To create a new article by filling out a form.

Discussion


At a high-level, we want to do the following:

  1. Go to the articles index page
  2. Click on the 'New Article' link
  3. Fill out the article title and description
  4. Click 'Submit' button
  5. The new article must be listed in the articles index page.

Steps


Step 1

Create a new file called manage_articles_spec.rb in spec/features folder. Add the following contents:

require 'rails_helper'
require 'spec_helper'

feature "Manage Articles", :type => :feature do
  it 'should be able to create a new article' do
    visit articles_path

    click_link 'New Article'
    fill_in "Title", with: 'Test Article'
    fill_in "Description", with: 'Body of the article'
    click_button 'Submit'

    expect(page).to have_text('Test Article')  
  end

end

Step 2

Run the manage_articles_spec.rb.

$ rspec spec/features/manage_articles_spec.rb 

 1) Manage Articles should be able to create a new article
     Failure/Error: click_link 'New Article'
     Capybara::ElementNotFound:
       Unable to find link "New Article"

Step 3

Add the link to the articles/index.html.erb file:

<%= link_to 'New Article', new_article_path %>

Step 4

Run the test. It fails.

1) Manage Articles should be able to create a new article
     Failure/Error: Unable to find matching line from backtrace
     AbstractController::ActionNotFound:
       The action 'new' could not be found for ArticlesController

Step 5

Add an empty new action to the articles controller:

def new
end

Step 6

Run the test. It fails.

1) Manage Articles should be able to create a new article
     Failure/Error: Unable to find matching line from backtrace
     ActionView::MissingTemplate:
       Missing template articles/new, application/new with {:locale=>[:en], :formats=>[:html, :xml], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}. Searched in:
         * "/Users/zepho/projects/tdd/basics/blog/app/views"

Step 7

Add the articles/new.html.erb.

<%= form_for @article do |f| %>
  <p>
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </p>

  <p>
    <%= f.label :description %><br>
    <%= f.text_area :description %>
  </p>

  <p>
    <%= f.submit 'Submit' %>
  </p>
<% end %>

Step 8

Run the test. It fails.

1) Manage Articles should be able to create a new article
    Failure/Error: Unable to find matching line from backtrace
    ActionView::Template::Error:
     First argument in form cannot contain nil or be empty

Step 9

Change the new action as follows:

  def new
    @article = Article.new
  end

Step 10

Run the test

 1) Manage Articles should be able to create a new article
     Failure/Error: Unable to find matching line from backtrace
     AbstractController::ActionNotFound:
       The action 'create' could not be found for ArticlesController

Step 11

Add the create method in articles controller:

  def create

  end

Step 12

Run the test. It fails.

    Failure/Error: Unable to find matching line from backtrace
     ActionView::MissingTemplate:
       Missing template articles/create, application/create with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}. Searched in:
         * "/Users/zepho/projects/tdd/basics/blog/app/views"

Step 13

We want the user to be redirected to the index page. So, change the create action:

  def create

    redirect_to articles_path
  end

Step 14

Run the test. It fails.

 1) Manage Articles should be able to create a new article
     Failure/Error: expect(page).to have_text('Test Article')
       expected to find text "Test Article" in "Listing Articles New Article"
     # ./spec/features/manage_articles_spec.rb:13:in `block (2 levels) in <top (required)>'

Step 15

Change the create action :

  def create
    allowed_params = params.require(:article).permit(:title, :description)
    Article.create(allowed_params)

    redirect_to articles_path
  end

Step 16

Run the test. It fails.

  1) Manage Articles should be able to create a new article
     Failure/Error: expect(page).to have_text('Test Article')
       expected to find text "Test Article" in "Listing Articles New Article"
     # ./spec/features/manage_articles_spec.rb:13:in `block (2 levels) in <top (required)>'

Step 17

Change the articles/index.html.erb as follows:

<h1>Listing Articles</h1>

<table >
  <thead>
    <tr>
      <th>Title</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <% @articles.each do |article| %>
      <tr>
        <td><%= article.title %></td>
        <td><%= article.description %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<%= link_to 'New Article', new_article_path %>

Step 18

Run the test. The test now passes.

Summary


In this lesson, we started with a high level view of the steps needed to create a new article by filling out a form. We wrote a feature test that drove us to make to make the necessary changes to implement creating a new article feature. The following steps were all driven by the test.

  1. We wrote a feature test to create a new article
  2. Changed view to add a link
  3. Changed controller to implement the functionality
  4. Added form for the user to fill out the article title and description
  5. Displayed an empty article form
  6. Allowed the user to fill out the article form and submit it to create an article.
  7. Displayed the article in the article index page.


Related Articles


Ace the Technical Interview

  • Easily find the gaps in your knowledge
  • Get customized lessons based on where you are
  • Take consistent action everyday
  • Builtin accountability to keep you on track
  • You will solve bigger problems over time
  • Get the job of your dreams

Take the 30 Day Coding Skills Challenge

Gain confidence to attend the interview

No spam ever. Unsubscribe anytime.