How to create todo list app in rails static pages

22 Mar 2014

Posted by Milos Dolobac

In the following series of posts we gonna create todo list app in rails. In this tutorial we’ll create basic structure of our app. In first part of tutorial you will learn:

  • How to install Rails
  • How to choose text editor for your operating system
  • How to use Rails in command line
  • How to use Bundler to install gems
  • How to use Cucumber with Capybara to test our pages
  • How to create our static_pages(home,about,contact)

1 What do you need

  • You need to have some basic knowledge of HTML, CSS. If you haven’t learn them yet go to web tutorial on codecademy

  • You need to have basics in Ruby. If you haven’t I wrote post about learning resources for ruby

  • You need to have ruby and ruby on rails installed. I will explain this in next section

2 How to install Ruby

In this post I’ve included installation instructions for Ruby and Rails

3 Choosing your text editor

You write all your ruby programs using text editor.

3.1 Notepad++

For Windows I recommend you this editor. It’s free and it includes syntax highlighting and auto completion for ruby.

3.2 TextMate

On Mac you can use TextMate. You can download it and install for free.

3.3 Gedit

On Linux you can use gedit.

4 Creating basic structure of the app

Ok so you’ve got your tools in order, so we can start to create application. Open up terminal window or command prompt if you’re on Windows and enter following code:

$ rails new todo --skip-test-unit

This will create rails application named todo. It takes a while. Ok let’s check out some folders that we’re created.


That’s the file that you will use to install all dependencies what you need for your applications. They’re called gems. Just add name of gem to your Gemfile and let Bundler to take care of installation.


In this folder you place your html templates.


Images, Javascript and CSS files belongs here.

4.1 How to use Bundler

After creating rails application you should use Bundler to use all dependencies what you need. First add name of the gem to your Gemfile, then open up terminal and add following command:

$ bundle install

Let’s add some gems to your Gemfile. Open up your Gemfile and add following gems:

gem 'slim-rails'
gem 'capybara'
gem 'cucumber-rails', :require => false
gem 'database_cleaner'
gem 'rspec-expectations'
gem 'selenium-webdriver'

Install it with Bundler:

$ bundle install

4.2 Starting our application

To run your application, type this into command line:

$ rails server

Go to web browser and type localhost:3000. Your output screen should look like this:


5 Creating Static Pages

We have our web server running let’s build some pages.

5.1 Creating controllers

 $ rails generate controller StaticPages home help about --no-test-framework

If you open your views folder, you should see that you have new folder named static_pages with some files in it. Go to the config/routes.rb, you should see path of our pages that we’re created. Type for example, localhost:3000/static_pages into your web browser.


We created StaticPages controller and we can populate our files. Testing every change in a browser would be tedious. So we gonna need Cucumber and Capybara to do it for us.

5.2 Cucumber

Cucumber lets software developers and shareholders to use simple plain language to describe features. If you want to know more about Cucumber, try CucumberBook #### How Cucumber works

Cucumber works in features which are written in plain text and step definitions which are written in regular ruby code. If you go to your app folder, you should see that folder named features was created.

First we need to setup folder structure of Cucumber. Run following command:

$ rails generate cucumber:install

We need to test all our static pages. Open up folder features in your main directory and add file static_pages.feature into your features directory.


Feature: Static Pages content

 User should see static pages content

 Scenario Outline: Path testing

    When I visit <Path> path 
    Then I should see following content: <Content>
      | Path     | Content | 
      | Home     | Todo    |
      | About    | About   |
      | Help     | Help    |



This is how it works. At first line you define your feature, in our example StaticPages content. Then you define your steps. Steps always begin with keywords: Given,When,Then,And and continue with regular expression. It can be any text. Don’t forget to surround your text in regular expression like this: /^some text$/

We have our feature defined, let’s test it with Cucumber

 $ cucumber

You should see something like this:

failing steps

Ok we’ve saw undefined scenarios and steps let’s actually implement it. Open up folder step-definitions and create file static_pages_steps.rb


When /^I visit Home path$/ do 
  visit 'static_pages/home'

In first line we match name of our step with name in the feature file. Then we use capybara to visit home path in the browser. Run your test with cucumber. You should see one passing test.

Now we need to test content of our home page. Add this into features/step_definitions/static_pages_steps.rb:

Then /^I should see following content: Todo$/ do
  expect(page).to have_content("Todo")

In first line we match second step with feature file. On the second line we use Rspec Expectations to test content of our home page.

Run cucumber again. You should see failing tests. Of course that test is falling, we don’t have content Todo in our templates.

Open up folder app/views/static_pages and edit file named home.html.slim.

5.3 Why to use Slim

Maybe you wonder why we’re using files with slim ending. Slim is a template language that strips all unnecessary elements as opening and closing tags. For example this is a code in html:

    <title>My WebPage</title>
    <h1>My heading</h1>
    <p>My paragraph</p>


And this is code in Slim:

     title My WebPage
      h1 My heading
      p My paragraph

You see that Slim code is shorter and easier to read as Html code. Let’s return to our file. Replace content of home.html.slim with following content:


h1 Todo 

You should see that our test is now passing. Implement this to remaining steps in our feature file.


When /^I visit About path$/ do
  visit 'static_pages/about'

Then /^I should see following content: About$/ do
  expect(page).to have_content("About")

When /^I visit Help path$/ do
  visit 'static_pages/help'

Then /^I should see following content: Help$/ do
  expect(page).to have_content("Help")


 h1 About


 h1 Help

All our tests are now passing, next step will be implement title tests. Open up your static_pages.feature file and append following line:


 And I should see following title: <Title>

   | Path     | Content | **Title |**
   | Home     | Todo    | **Todo  |**
   | About    | About   | **About |**
   | Help     | Help    | **Help  |**

Let’s implement our test. Add these lines to our steps file.


And /^I should see following title: Todo$/ do
  expect(page).to have_title("Todo")

And /^I should see following title: About$/ do
  expect(page).to have_title("About")

 And /^I should see following title: Help$/ do
  expect(page).to have_title("Help")

Let’s fix failing tests. We need to change our title in our templates.


    title Todo


    title About


    title Help

Let’s run cucumber again. You should see that’s all our steps are now passing. We are done.

6 What to improve

6.1 Watching step changes with Guard

There’s lot a place to improve. For example running cucumber every time for every change in terminal it’s disgusting. Let’s change it. We can use Guard to watch every change in our features folder. Add Guard to your Gemfile.

gem 'guard-cucumber' 

And install it:

$ bundle install

Let’s add Guard to Cucumber.

$ guard init cucumber

If you open your app’s folder you should see that file named Guardfile was created.

Let’s run Guard to run our features automatically.

$ guard

All features are running automatically by now.

6.2 Eliminate duplication in title

Take a look at files in views folder. You saw that we’ve writed title tag three times. That’s terrible, let’s do something about that. First rename file in app/views/layouts directory.

mv application.html.erb application.html.slim

Delete all content and replace it with following:


doctype html
    title Todo
    = stylesheet_link_tag    "application", media: "all", "data-turbolinks-track" => true
    = javascript_include_tag "application", "data-turbolinks-track" => true
    = csrf_meta_tags
    = yield


- provide(:title, 'About')
h1 About


 - provide(:title, 'Help')
h1 Help

6.3 Linking our pages and updating routes

Typing long adresses like static_pages/home is very disgusting, if we instead use shorter address, it wouldbe much better.

Open up config/routes.rb and replace it content with following:

root "static_pages#home"
match "/help", to: "static_pages#help", via: 'get'
match "/about", to: "static_pages#about", via: 'get'

And change tests in features/step_definitions/static_pages_steps.rb like this:


When /^I visit Home path$/ do
  visit '/'

When /^I visit About path$/ do
  visit '/about'

When /^I visit Help path$/ do
  visit '/help'

Let’s take a look at code we’ve just wrote.

root "static_pages#home"

This code creates root path for our pages. In this time it’s static_pages#home. So you don’t have to write your path to web browser. Start rails server. You should something like this:


That’s good but your visitors don’t have time to write short path like /help to your webrowser. You haveto include links on your root page.

Add this code for adding links to your app/views/static_pages/layouts/application.html file after the body tag.


    li = link_to "Home", root_path
    li = link_to "Help", help_path
    li = link_to "About", about_path

You should see links on your home page.

linked pages

We’re done here. In next tutorial we’ll do some styling to our app

comments powered by Disqus