named route not working -- input hash completely ignored

I have been reading that you can pass a parameters hash to a named
route:
<p>You can get <%= link_to "help!", assist_path(:action => "membership")
%></p>
<p>You can get <a href="/assistance/membership">help!</a></p>

Now, for me, I have the following named route:

# the bootcamp calendar
map.bootcamp_calendar "/boot_camp_info/Calendar/:year/:month",
      :controller => "boot_camp_info",
      :action => "Calendar",
      :requirements => {:year => /\d{4}/,:month => /\d{1,2}/},
      :defaults => {:year => Date.today.year, :month =>
Date.today.month}

However, my code
<p><%= link_to "Prev", bootcamp_calendar_path(:year => '2008', :month =>
'3') %></p>

Produces <a href="/boot_camp_info/Calendar">Prev</a> not <a
href="/boot_camp_info/Calendar/2008/3">Prev</a>

In fact, when debugging, bootcamp_calendar_path(:year => '2008', :month
=> '3') resolves to /boot_camp_info/Calendar and neglects the hash
values.

I have fought with this for awhile, but I am at a loss. I have traced
all the rails code I can find, but don't see where things could be going
wrong.

Any help greatly appreciated.

regards,

tim

Hi --

I have been reading that you can pass a parameters hash to a named
route:
<p>You can get <%= link_to "help!", assist_path(:action => "membership")
%></p>
<p>You can get <a href="/assistance/membership">help!</a></p>

Now, for me, I have the following named route:

# the bootcamp calendar
map.bootcamp_calendar "/boot_camp_info/Calendar/:year/:month",
     :controller => "boot_camp_info",
     :action => "Calendar",

It's much better to use lowercase names for methods. Uppercase names
are legal (and there are a few even built into Ruby), but they're very
unidiomatic for controller actions (and most purposes).

     :requirements => {:year => /\d{4}/,:month => /\d{1,2}/},
     :defaults => {:year => Date.today.year, :month =>
Date.today.month}

However, my code
<p><%= link_to "Prev", bootcamp_calendar_path(:year => '2008', :month =>
'3') %></p>

Produces <a href="/boot_camp_info/Calendar">Prev</a> not <a
href="/boot_camp_info/Calendar/2008/3">Prev</a>

There's no need for the defaults to be put explicitly in the path,
because when you click on the version without them, they'll be
interpolated anyway. It's an example of the fact that the routing
system only makes sense to itself. When it produces a path string,
it's producing a string that may not have a lot of human-readable
info, but that will be understood (including interpolation of
defaults) by the URL recognition process.

David

David,

Thank you so much for your reply. However, after reading your message
several times, I am confused what you are recommending. Got it on the
capitalization of the controller, put that in their early before I
understood rails naming conventions. You don't think that is causing the
problem, correct?

I am not trying to put defaults in the path -- I am trying to link to a
specific month and year. I really need
href="/boot_camp_info/Calendar/2008/3". With my named route, I would
really like to get bootcamp_calendar_url(:year => @myyear, :month =>
@mymonth) to point to a specific year and month.

I have this working via a helper I made, I know I could even do:

<%= link_to "Next month",
"#{bootcamp_calendar_path}/#{@myyear}/#{@mymonth}" %>

but after reading the documentation, I think
bootcamp_calendar_path(:year => '2008', :month => '3') should work and I
am really nervous that rails says it can do something that it doesn't do
-- and no errors are returned. so i have things working, but I am
worried that other things in rails might not be working as well. Do I
have a legitimate bug here -- or am i doing something wrong?

best,

tim

David A. Black wrote:

Tim Booher wrote:

I am not trying to put defaults in the path -- I am trying to link to a
specific month and year. I really need
href="/boot_camp_info/Calendar/2008/3". With my named route, I would
really like to get bootcamp_calendar_url(:year => @myyear, :month =>
@mymonth) to point to a specific year and month.

As David said, Rails doesn't need this because of your defaults. These
mean that:

/boot_camp_info/Calendar

will be filled in with the default year and month, so if you try to
create a link for the current year and month, Rails knows these are not
required in the link so doesn't include them.

Rails uses all the information in your routes file to determine an
appropriate URL for your request. Because you are specifying defaults,
you are telling Rails that those values are optional, so Rails knows it
can generate URLs without them and the result will be meaningful.

If the year and month must always be included in the URL, then don't
supply defaults and always specify the values when creating your URLs.

Hi --

David,

Thank you so much for your reply. However, after reading your message
several times, I am confused what you are recommending. Got it on the
capitalization of the controller, put that in their early before I
understood rails naming conventions. You don't think that is causing the
problem, correct?

I am not trying to put defaults in the path -- I am trying to link to a
specific month and year. I really need
href="/boot_camp_info/Calendar/2008/3". With my named route, I would
really like to get bootcamp_calendar_url(:year => @myyear, :month =>
@mymonth) to point to a specific year and month.

I have this working via a helper I made, I know I could even do:

<%= link_to "Next month",
"#{bootcamp_calendar_path}/#{@myyear}/#{@mymonth}" %>

but after reading the documentation, I think
bootcamp_calendar_path(:year => '2008', :month => '3') should work and I
am really nervous that rails says it can do something that it doesn't do
-- and no errors are returned. so i have things working, but I am
worried that other things in rails might not be working as well. Do I
have a legitimate bug here -- or am i doing something wrong?

Definitely not a bug. What you're not taking into account (and see
Mark's answer too) is that the routing system talks to itself.

Given the defaults you've specified, when you click on this:

   "/boot_camp_info/calendar"

the routing system knows that you mean:

   controller: boot_camp_info
   action: calendar
   params[:year]: "2008"
   params[:month]: "3"

That's what it means for there to be defaults. It doesn't mean that
they get inserted physically into the path; it means that *without*
having them physically present, the routing system knows that they're
what you want.

The routing system uses your routing rule to:

   1. write the path string;
   2. interpret a request URL that contains the path string.

Your rule specifies defaults; therefore, the system knows how to
interpret a request that has no explicit values in the :year and
:month positions. So that's what it writes, as the path, when it is
asked to use the defaults.

David