URL generation works for more complex routings as well. For example, the routing for our blog includes the following mappings. map.connect "blog/:year/:month/:day", :controller => "blog", :action => "show_date", :requirements => { :year => /(19|20)\d\d/, :month => /[01]?\d/, :day => /[0-3]?\d/}, :day => nil, # optional :month => nil # optional map.connect "blog/show/:id", :controller => "blog", :action => "show", :id => /\d+/ # must be numeric map.connect "blog/:controller/:action/:id" Imagine the incoming request was http://pragprog.com/blog/2005/4/15. This will have been mapped to the show_date action of the Blog controller by the first rule. Let’s see what various url_for( ) calls will generate in these circumstances. If we ask for a URL for a different day, the mapping call will take the values from the incoming request as defaults, changing just the day parameter. url_for(:day => "25") #=> http://pragprog.com/blog/2005/4/25 Now let’s see what happens if we instead give it just a year. url_for(:year => "2004") #=> http://pragprog.com/blog/2004 That’s pretty smart. The mapping code assumes that URLs represent a hierarchy of values.2 Once we change something away from the default at one level in that hierarchy, it stops supplying defaults for the lower levels. This is reasonable: the lower-level parameters really make sense only in the context of the higher level ones, so changing away from the default