Quest for the Holy Rails

May 7, 2007

The Welcome Controller

Filed under: pente, rails — Jake Brownson @ 1:27 am

In the last post we created the Rails project and added authentication. In this post we will add a welcome controller.

Our welcome controller will be very simple for now. It will just have links for the options available to the user depending on if they’re logged in or not.

Let’s go ahead and generate the controller:

jake@jake-laptop:~/src/pente$ script/generate controller welcome

      exists  app/controllers/

      exists  app/helpers/

      create  app/views/welcome

      exists  test/functional/

      create  app/controllers/welcome_controller.rb

      create  test/functional/welcome_controller_test.rb

      create  app/helpers/welcome_helper.rb

jake@jake-laptop:~/src/pente$

Let’s add an index action. Since we’re using TDD let’s add a functional test in test/functional/welcome_controller_test.rb that fails because we don’t have one:

require File.dirname(__FILE__) + '/../test_helper'

require 'welcome_controller'# Re-raise errors caught by the controller.

class WelcomeController; def rescue_action(e) raise e end; end

class WelcomeControllerTest < Test::Unit::TestCase

def setup

    @controller = WelcomeController.new

    @request    = ActionController::TestRequest.new

    @response   = ActionController::TestResponse.new

  end

def test_should_have_index

    get :index

    assert_response :success

  end

end

Run the test:

jake@jake-laptop:~/src/pente$ rake

(in /home/jake/src/pente)

/usr/bin/ruby1.8 -Ilib:test "/var/lib/gems/1.8/gems/rake-0.7.3/lib/rake/rake_test_loader.rb" "test/unit/player_test.rb"

Loaded suite /var/lib/gems/1.8/gems/rake-0.7.3/lib/rake/rake_test_loader

Started

.............

Finished in 0.086673 seconds.13 tests, 26 assertions, 0 failures, 0 errors

/usr/bin/ruby1.8 -Ilib:test "/var/lib/gems/1.8/gems/rake-0.7.3/lib/rake/rake_test_loader.rb" "test/functional/sessions_controller_test.rb" "test/functional/welcome_controller_test.rb" "test/functional/players_controller_test.rb"

Loaded suite /var/lib/gems/1.8/gems/rake-0.7.3/lib/rake/rake_test_loader

Started

..............E

Finished in 0.137953 seconds.

1) Error:

test_should_have_index(WelcomeControllerTest):

ActionController::UnknownAction: No action responded to index

    /var/lib/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/filters.rb:632:in `call_filter'

    /var/lib/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/filters.rb:638:in `call_filter'

    /var/lib/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/filters.rb:438:in `call'

    /var/lib/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/filters.rb:637:in `call_filter'

    /var/lib/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/filters.rb:619:in `perform_action_without_benchmark'

    /var/lib/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/benchmarking.rb:66:in `perform_action_without_rescue'

    /usr/lib/ruby/1.8/benchmark.rb:293:in `measure'

    /var/lib/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/benchmarking.rb:66:in `perform_action_without_rescue'

    /var/lib/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/rescue.rb:83:in `perform_action'

    /var/lib/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/base.rb:430:in `send'

    /var/lib/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/base.rb:430:in `process_without_filters'

    /var/lib/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/filters.rb:624:in `process_without_session_management_support'

    /var/lib/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/session_management.rb:114:in `process_without_test'

    /var/lib/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/test_process.rb:15:in `process'

    /var/lib/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/test_process.rb:382:in `process'

    /var/lib/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/test_process.rb:353:in `get'

    ./test/functional/welcome_controller_test.rb:16:in `test_should_have_index'

15 tests, 26 assertions, 0 failures, 1 errors

/usr/bin/ruby1.8 -Ilib:test "/var/lib/gems/1.8/gems/rake-0.7.3/lib/rake/rake_test_loader.rb"

Command failed with status (1): [/usr/bin/ruby1.8 -Ilib:test "/var/lib/gems...]

/var/lib/gems/1.8/gems/rake-0.7.3/lib/rake.rb:719:in `sh'

/var/lib/gems/1.8/gems/rake-0.7.3/lib/rake.rb:726:in `call'

... snip ...

/var/lib/gems/1.8/bin/rake:18:in `load'

/var/lib/gems/1.8/bin/rake:18

rake aborted!

Test failures

(See full trace by running task with --trace)

jake@jake-laptop:~/src/pente$

Alright we’re in the red now so let’s implement the code:

app/controllers/welcome_controller.rb:

class WelcomeController < ApplicationController  def index

  end

end

app/views/welcome/index.rhtml:

Welcome!

Run the test agan and we’re in the green:

jake@jake-laptop:~/src/pente$ rake

(in /home/jake/src/pente)

/usr/bin/ruby1.8 -Ilib:test "/var/lib/gems/1.8/gems/rake-0.7.3/lib/rake/rake_test_loader.rb" "test/unit/player_test.rb"

Loaded suite /var/lib/gems/1.8/gems/rake-0.7.3/lib/rake/rake_test_loader

Started

.............

Finished in 0.100943 seconds.13 tests, 26 assertions, 0 failures, 0 errors

/usr/bin/ruby1.8 -Ilib:test "/var/lib/gems/1.8/gems/rake-0.7.3/lib/rake/rake_test_loader.rb" "test/functional/sessions_controller_test.rb" "test/functional/welcome_controller_test.rb" "test/functional/players_controller_test.rb"

Loaded suite /var/lib/gems/1.8/gems/rake-0.7.3/lib/rake/rake_test_loader

Started

...............

Finished in 0.145732 seconds.

15 tests, 27 assertions, 0 failures, 0 errors

/usr/bin/ruby1.8 -Ilib:test "/var/lib/gems/1.8/gems/rake-0.7.3/lib/rake/rake_test_loader.rb"

jake@jake-laptop:~/src/pente$

Before we forget let’s get rid of the public/index.html file so when we use WEBrick we get the correct page. The file doesn’t hurt the tests, but this is a good time to remove it anyway, and while we’re at it we’ll map our welcome controller to ” so it shows up by default:

jake@jake-laptop:~/src/pente$ rm public/index.html

jake@jake-laptop:~/src/pente$

config/routes.rb:

ActionController::Routing::Routes.draw do |map|

  map.resource :players, :sessions

  map.connect '', :controller => "welcome"

  map.connect ':controller/:action/:id.:format'

  map.connect ':controller/:action/:id'

end

Now we want to add some useful links to the welcome page. So far the only think a user can do is signup, login and logout. Let’s add some tests to check for this functionality. I’m adding more than one test at a time here to speed things up since this is pretty basic:
test/functional/welcome_controller_test.rb:

require File.dirname(__FILE__) + '/../test_helper'

require 'welcome_controller'# Re-raise errors caught by the controller.

class WelcomeController; def rescue_action(e) raise e end; end

class WelcomeControllerTest  'a', :attributes => {'href' => x}

    end

  end

def test_should_have_links_when_logged_in

    login_as 'aaron'

    get :index

    ['/sessions/destroy'].each do |x|

      assert_tag :tag => 'a', :attributes => {'href' => x}

    end

  end

end

I’ve been doing a lot of thinking about REST and I think I’ve found a compromize that will keep all the main benefits of REST without any of the ugly javascript hacks. I will use RESTful URLs in links when it’s possible, but resort to classic Rails controller/action/id style links when it avoids an ugly Javascript hack. I still get the REST web API as I’m not disabling the REST interface, and the HTML doesn’t have the ugly hacks.

Now let’s make them pass by modifying app/views/welcome/index.rhtml:

<ul>

<% if logged_in? -%>

  <li><a href='/sessions/destroy'>Logout</a></li>

<% else -%>

  <li><a href='/sessions/new'>Login</a></li>

  <li><a href='/players/new'>Signup</a></li>

<% end -%>

</ul>

We’re now back in the green with a working welcome controller! From here on out I’m going to skip copy/pasting the test results when they all pass to save space and time. You might not be convinced the login controller is actually working because we haven’t actually seen it in the browser. That’s one of the great things about TDD. You don’t have to rely on randomly clicking links in a browser to make sure things are working. Go ahead and fire up WEBrick (scripts/server) and see for yourself!

I’m going to be saving all the HTML/CSS prettification for the end of the project and keep the interfaces plain for now.

In the next post I’ll add a games resource and tie it to the players resource.

1 Comment »

  1. Pull out…

    Comment by Follow this — June 10, 2008 @ 7:32 am


RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.