A Ruby on Rails version 4.0.0.beta app


      This website illustrates using the Rubygem 'routesfordummies'. Try clicking on this:
      /new/foo/bar/fubar/snafu/snafu?foo=bar&situation=normal

      compared with this:
      /old/foo/bar/fubar/snafu/snafu?foo=bar&situation=normal

      Look at the routes.rb file, and see if you can work out a URL beginning with '/old' which DOES work:
      get 'old/:version/:scope' => 'old#an_action' get 'old/:version/:media/:id/:scope' => 'old#an_action' get 'old/:version/:scope/:id/media.:format' => 'old#an_action'
      The above is a genuine example from a production app I worked on.
      It's a small section of a very complex routes.rb file.

      Testing controllers is more difficult than it need be with routes.rb.
      The combination of complex patterns in routes.rb and checking the contents of
      the params hash in your controllers' public methods means you are
      testing two independent things at the same time - this is not a good idea.
      If they are both wrong, your test might pass.

      Imagine a Test::Unit functional test for the old_controller. Suppose the params hash contains
      :scope => 'foo', :media => ''
      Which of the three 'get' actions listed in the section of routes.rb above was called?
      It's difficult to tell. The real world example I referred to is much more complicated than this.

      'routesfordummies' is an attempt at a solution to this complexity. The basic idea is to put all
      the URL-logic in one place, in a controller action, and virtually nothing in routes.rb.

      This is the section of routes.rb for URLs beginning with '/new':
      get 'new/:a' => 'new#an_action' get 'new/:a/:b' => 'new#an_action' get 'new/:a/:b/:c' => 'new#an_action' get 'new/:a/:b/:c/:d' => 'new#an_action' get 'new/:a/:b/:c/:d/:e' => 'new#an_action'
      It's much simpler.

      The full routes.rb file is here

      And here's a section of a controller using 'routesfordummies':
      require 'routesfordummies' include Routesfordummies class NewController < ApplicationController def an_action @array = url2array @hash = params2hash # Error checking raise "The first part of the URL after '/new/' should be 'foo'!!!'" unless @array[ 0 ] == 'foo' raise "The parameter list should include 'situation'!!!" unless @hash.keys.include? 'situation' # Select private methods to call based on what is in the url and the parameters ... end private ... end


      Finally, here's config/initializers/routesfordummies_initializer.rb which sets up routes when the app starts, using the routesfordummies gem:
      require 'routesfordummies' include Routesfordummies insertabcdroutes( :verb => 'get', :app => 'Rockonruby', :controller => 'dummy', :action => 'an_action' )

      Try this: /dummy/one/two/hello/world/bar/fubar/snafu/snafu?bar=foo,
      or any other URL beginning /dummy/, followed by at least one word, and optional parameters.

      All that is needed is to add to the 'an_action' method in dummy_controller.rb
      url and parameter checking, then calls to private methods based on the url and the parameters.
      This is a lot easier than maintaining the routes.rb file.