Rails Deep Dive: Loccasions, Home Page

Glenn Goodrich
Ruby Editor
This entry is part 6 of 15 in the series Loccasions

Loccasions

In the last post, we ended with our application structure. In this post, we’ll start with our first user story As an unregistered user, I want to see the home/landing page. There are a few things to point out in this short user story. First, we have identified a role of the application in the form of an unregistered user. Also, the story tells us that we need to have a home page that is not protected by authorization.

Mocking Up the Home Page

This page is the front door of our application, and anyone can knock on it. At this point, it’d be nice to have a talented web designer on the team who could crank out a simple, elegant page. Unfortunately, we just have me, and my design skills are, um, raw. coughs
I like to sketch out wireframes when someone can’t afford a real designer, er, I mean, when I am designing a page. There are a plethora of mockup tools on the interwebs (and there is paper and pencil virtually everywhere) and I’ve settled on MockupBuilder because my usual tool (Pencil) is on sabbatical or something. I have cranked out a quick mockup here:

Our blueprint

It’s a simple, if criminally familiar, home page. There are links to sign in and register, a largish image to promote the site, and a divided area below to put information about the awesome of Loccasions. The layout feeds into a grid system nicely, which is no mistake.

Prepare the Test Environment

Before we take that mockup through the looking glass, we need to setup our test environment and write a test (or two) to validate our page. I mentioned Daniel Kehoe’s (@rails_apps) excellent tutorials in the last post, and I am relying heavily on them to setup the test environment for Loccasions.

Setup RSpec

RSpec comes with generators to setup the environment, so open up a terminal, cd into the loccasions directory and type:

rails g rspec:install

The output to this command complained that the Mongoid config didn’t exist (ugh, first mistake), so we need to generate it.

rails g mongoid:config

That gives us a config/mongoid.yml that will drive the creation of our databases in MongoDB. Re-running rails g rspec:install and rspec is happy (unless, MongoDB is not running) again.

We aren’t going to use ActiveRecord in Loccasions, so we have to comment out a couple of lines in the spec/spec_helper.rb file. Comment out these lines:

# config.fixture_path = "#{::Rails.root}/spec/fixtures"
# config.use_transactional_fixtures = true

In between test suites, we want RSpec to clean up the database. The database_cleaner gem performs this task for us. Add the following to the spec/spec_helper.rb file.

# Clean up the database
require 'database_cleaner'
config.before(:suite) do
  DatabaseCleaner.strategy = :truncation
  DatabaseCleaner.orm = "mongoid"
end

config.before(:each) do
  DatabaseCleaner.clean
end

Also in the spec_helper.rb file, add

require 'capybara/rspec'</code>

to get the capybara RSpec matchers.

The mongoid-rspec gem gives us some nice RSpec matchers to help our tests communicate their purpose more effectively. These matchers are added to RSpec by creating a spec/support/mongoid.rb (you’ll have to create the support directory too) file with the following:

RSpec.configure do |config|
  config.include Mongoid::Matchers
end

That gets our test environment into a state that we can get going. There are still a couple of things to set up, but we’ll do that when it’s more pressing. Just to make sure that we haven’t broken anything, run rake -T at the command prompt and make sure you see the RSpec tasks. If all is well, run rake spec and RSpec should tell you that it has nothing to do, which is a good thing.

Our First Test

Looking at our current user story, an unregistered user needs to see our home page. How do we measure that we’ve met this story? What will the home page have that we can confirm and know we’re OK? My first thoughts on what to measure are:

  • The page has a ‘Sign In’ link
  • The page title is ‘Loccasions: Home’
  • The page has ‘What is Loccasions?’ somewhere on it. (We want to explain ourselves…)

We’ll start by using Capybara’s new feature syntax in our first acceptence test. Create a file called spec/acceptance/home_page_spec.rb (you’ll have to create the acceptance directory as well) with the following content:
require ‘spec_helper’

feature 'Home Page', %q{
  As an unregistered user
  I want to see the home/landing page
} do
  background do
    # Nothing to do here
  end

  scenario "Home page" do
    visit "/"
    page.should have_link('Sign In')
    page.should have_selector('title', :text => "Loccasions")
    page.should have_content('What is Loccasions?')
  end

end

This spec is very easy to read and looks for the items we are using to measure success. By starting with an acceptance test, we are driving the design from the user’s perspective. Running rake spec results in:

Awww...our first spec...

As expected, the spec fails trying to find a “Sign In” link. Right now, we are still using the default index.html in the public directory, so let’s delete it. Running the spec again, we now see a “Routing error” which, again, makes sense as we have no root route. Based on previous Rails apps and convention, let’s make a “Home” controller with an “index” action.

rails g controller Home index

ERB? Que pasa??

Hmmm…something is not right. The generator created an ERB template instead of a Haml template. I swear I’ve read that, at 3.1, including Haml in your Gemfile will automatically make it the default template_engine. Seems I am incorrect. Oh well, the quick solution is to add gem "haml-rails", "~> 0.3.4" to our Gemfile and bundle install. Now, rerun the rails g controller Home index and voila!, we have a Haml template. (Oh, and go ahead and remove the app/views/home/index.html.erb file)

Next, we need to point our root path to the index method on our new controller. Open up config/routes.rb, remove the get "home#index" line and replace it with root :to => "home#index". Running the spec again brings the return of the no “Sign-In” link error.
In the interest of time and effort, I am going to jump ahead a bit and create the layout for our home page. I am using Skeleton, and have modified the app/views/layouts/application.html.haml (I migrated the ERB layout file to Haml) and the app/views/home/index.html.haml files accordingly. Here is what you need to do to catch up:

  • Download and uncompress Skeleton.
  • Copy the files from the javascript and stylesheets directories to those same directories in app/assets/
  • Replace the contents of your app/views/layouts/application.html.haml file with the content here
  • Replace the contents of your app/views/home/index.html.haml file with the content here
  • Replace the contents of your app/assets/stylesheets/home.css.sass file with the content here
  • Copy to your app/assets/images directory

If you rerun the spec, it passes.

Pass me on the lefthand side

Just like that, our first user story is complete. It’s Miller Time!

Feel free to look over the layout and index Haml files and see how I met our spec. Once you are comfortable with Haml’s syntax, the details of our layout is much less interesting.

git add .
git commit -am "Added home page and layout"
git push origin master

Next time, we’ll start with another user story and see where that takes Loccasions. As always, I am interested in your opinions and comments about how the series is playing out.

BTW, the font used for the Loccasions header is Eight One by glue.

Loccasions

<< Rails Deep Dive: Application Setup, LoccasionsRails Deep Dive: Loccasions, Authentication >>

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Manoj

    Excellent series and step by step coverage of creating a Rails App.

    • http://www.ruprict.net/ Glenn Goodrich

      Thanks Manoj!

  • Peter Nunn

    Hi Glenn,

    following along this bouncing ball but have hit some issues with the rake spec bits it seems (know nothing about rails at this point).

    I’m running on ubuntu 11.04 and am getting the following.

    rake spec
    NOTE: Gem.available? is deprecated, use Specification::find_by_name. It will be removed on or after 2011-11-01.
    Gem.available? called from /home/pnunn/.rvm/gems/ruby-1.9.2-p290@loccasions/gems/jasmine-1.0.2.1/lib/jasmine/base.rb:64.
    /home/pnunn/.rvm/rubies/ruby-1.9.2-p290/bin/ruby -S bundle exec rspec ./spec/views/home/index.html.erb_spec.rb ./spec/views/home/index.html.haml_spec.rb ./spec/helpers/home_helper_spec.rb ./spec/controllers/home_controller_spec.rb ./spec/acceptance/home_page_spec.rb
    NOTE: Gem.available? is deprecated, use Specification::find_by_name. It will be removed on or after 2011-11-01.
    Gem.available? called from /home/pnunn/.rvm/gems/ruby-1.9.2-p290@loccasions/gems/jasmine-1.0.2.1/lib/jasmine/base.rb:64.
    /home/pnunn/src/ruby/deepdive/loccasions/spec/spec_helper.rb:31:in `’: undefined local variable or method `config’ for main:Object (NameError)
    from /home/pnunn/src/ruby/deepdive/loccasions/spec/views/home/index.html.erb_spec.rb:1:in `require’
    from /home/pnunn/src/ruby/deepdive/loccasions/spec/views/home/index.html.erb_spec.rb:1:in `’
    from /home/pnunn/.rvm/gems/ruby-1.9.2-p290@loccasions/gems/rspec-core-2.6.4/lib/rspec/core/configuration.rb:419:in `load’
    from /home/pnunn/.rvm/gems/ruby-1.9.2-p290@loccasions/gems/rspec-core-2.6.4/lib/rspec/core/configuration.rb:419:in `block in load_spec_files’
    from /home/pnunn/.rvm/gems/ruby-1.9.2-p290@loccasions/gems/rspec-core-2.6.4/lib/rspec/core/configuration.rb:419:in `map’
    from /home/pnunn/.rvm/gems/ruby-1.9.2-p290@loccasions/gems/rspec-core-2.6.4/lib/rspec/core/configuration.rb:419:in `load_spec_files’
    from /home/pnunn/.rvm/gems/ruby-1.9.2-p290@loccasions/gems/rspec-core-2.6.4/lib/rspec/core/command_line.rb:18:in `run’
    from /home/pnunn/.rvm/gems/ruby-1.9.2-p290@loccasions/gems/rspec-core-2.6.4/lib/rspec/core/runner.rb:80:in `run_in_process’
    from /home/pnunn/.rvm/gems/ruby-1.9.2-p290@loccasions/gems/rspec-core-2.6.4/lib/rspec/core/runner.rb:69:in `run’
    from /home/pnunn/.rvm/gems/ruby-1.9.2-p290@loccasions/gems/rspec-core-2.6.4/lib/rspec/core/runner.rb:11:in `block in autorun’
    rake aborted!
    ruby -S bundle exec rspec ./spec/views/home/index.html.erb_spec.rb ./spec/views/home/index.html.haml_spec.rb ./spec/helpers/home_helper_spec.rb ./spec/controllers/home_controller_spec.rb ./spec/acceptance/home_page_spec.rb failed

    Tasks: TOP => spec
    (See full trace by running task with –trace)

    This is at the end of the article with all of your code added (wasn’t working before either). Any ideas?

    Peter

  • Lance

    Hi Glenn

    I’m having a wonderful time following your tutorial, but then i got to the part where i needed to create the file HOME_PAGE_SPEC.RB

    The code returns an error
    home/lance/RailsLoccasions/spec/spec_helper.rb:41:in `’: undefined local variable or method `config’ for main:Object (NameError)

    But it doesn’t return any if I empty the the file. So the bug must be in the chunk of code you provided. Also I noticed you mentioned

    require ‘spec_helper’

    But it wasn’t a part of the code for HOME_PAGE_SPEC.RB. Even if I include it, it still doesn’t work though.

    I cant make ‘rake spec’ run successfully. If this is vital for following your tutorial, I guess a lot of us following your example is going to have a hard time until this is address. Any guess?

    • Charles Lemmon

      I think I made the same mistake as Lance. The database cleaner code needs to go inside the do loop.

  • http://www.pixtur.org pixtur

    I love your tutorial. However, there is a tiny mistake in your test:

    page.should have_selector(‘title’, :content => “Loccasions”)

    should be…

    page.should have_selector(‘title’, :text => “Loccasions”)

    also see: https://github.com/rspec/rspec-rails/issues/478

    • http://www.ruprict.net/ Glenn Goodrich

      Thanks pixtur…fixed!

  • http://greg@icodeforu.com Greg

    I am determined to get this app done. I’m having the same problem as some others here. I’ve strarted over from scratch five times now and although it was a great practice/learning experience, I’m stuck at the first test. I even copied your code for my test file, mongo file, and spec file with no luck.

    I hate to put all this in the post, but this is what I’m getting:

    rake spec
    NOTE: Gem.available? is deprecated, use Specification::find_by_name. It will be removed on or after 2011-11-01.
    Gem.available? called from /Users/Greg/.rvm/gems/ruby-1.9.2-p320@loccasions/gems/jasmine-1.0.2.1/lib/jasmine/base.rb:64.
    /Users/Greg/.rvm/rubies/ruby-1.9.2-p320/bin/ruby -S bundle exec rspec ./spec/acceptance/home_page_spec.rb
    /Users/Greg/loccasions/spec/spec_helper.rb:2:in `require’: no such file to load — spork (LoadError)
    from /Users/Greg/loccasions/spec/spec_helper.rb:2:in `’
    from /Users/Greg/loccasions/spec/acceptance/home_page_spec.rb:1:in `require’
    from /Users/Greg/loccasions/spec/acceptance/home_page_spec.rb:1:in `’
    from /Users/Greg/.rvm/gems/ruby-1.9.2-p320@loccasions/gems/rspec-core-2.6.4/lib/rspec/core/configuration.rb:419:in `load’
    from /Users/Greg/.rvm/gems/ruby-1.9.2-p320@loccasions/gems/rspec-core-2.6.4/lib/rspec/core/configuration.rb:419:in `block in load_spec_files’
    from /Users/Greg/.rvm/gems/ruby-1.9.2-p320@loccasions/gems/rspec-core-2.6.4/lib/rspec/core/configuration.rb:419:in `map’
    from /Users/Greg/.rvm/gems/ruby-1.9.2-p320@loccasions/gems/rspec-core-2.6.4/lib/rspec/core/configuration.rb:419:in `load_spec_files’
    from /Users/Greg/.rvm/gems/ruby-1.9.2-p320@loccasions/gems/rspec-core-2.6.4/lib/rspec/core/command_line.rb:18:in `run’
    from /Users/Greg/.rvm/gems/ruby-1.9.2-p320@loccasions/gems/rspec-core-2.6.4/lib/rspec/core/runner.rb:80:in `run_in_process’
    from /Users/Greg/.rvm/gems/ruby-1.9.2-p320@loccasions/gems/rspec-core-2.6.4/lib/rspec/core/runner.rb:69:in `run’
    from /Users/Greg/.rvm/gems/ruby-1.9.2-p320@loccasions/gems/rspec-core-2.6.4/lib/rspec/core/runner.rb:11:in `block in autorun’
    rake aborted!
    ruby -S bundle exec rspec ./spec/acceptance/home_page_spec.rb failed

    Tasks: TOP => spec
    (See full trace by running task with –trace)

    Any help would be greatly appreciated.