Hi, I think there may be a bug in the named routes for handling routes that have optional parameters. For example, I have a route as follows: map.club_start ''club_start/:page'', :controller => ''clubs'', :action => ''start'' And if I link to it using the club_start_url, it will create a URL for: http://.../clubs/start Instead of the expected behavior of: http://.../club_start If I remove the :page parameter, it works as expected. Also, any forms on that clubs/start page that is rendered will automatically submit to the correct club_start URL, but they also include the :page parameter. Does this appear to be a valid bug? Thanks, Tom
On 8/4/05, Tom Davies <atomgiant-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hi, > > I think there may be a bug in the named routes for handling routes > that have optional parameters. For example, I have a route as > follows: > > map.club_start ''club_start/:page'', :controller => ''clubs'', :action => ''start'' > > And if I link to it using the club_start_url, it will create a URL for: > > http://.../clubs/start > > Instead of the expected behavior of: > > http://.../club_start > > If I remove the :page parameter, it works as expected. Also, any > forms on that clubs/start page that is rendered will automatically > submit to the correct club_start URL, but they also include the :page > parameter. > > Does this appear to be a valid bug?Try this: map.club_start ''club_start/:page'', :controller => ''clubs'', :action => ''start'', :page => nil If you''re using :page for pagination, you could also do this: map.club_start ''club_start/:page'', :controller => ''clubs'', :action => ''start'', :page => ''1'' -- rick http://techno-weenie.net
Thanks Rick. That is a reasonable workaround. However, the named routes behave inconsistently in that if you pass it the :page, it will show the named route name, and if you don''t it will show you the :controller/:action. I believe this may still be a bug, but since I have a workaround I can live with it. If anyone else feels this should be logged as an issue, please let me know and I will log something in Trac. Otherwise, I will just happily use the workaround. Thanks, Tom On 8/4/05, Rick Olson <technoweenie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On 8/4/05, Tom Davies <atomgiant-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > Hi, > > > > I think there may be a bug in the named routes for handling routes > > that have optional parameters. For example, I have a route as > > follows: > > > > map.club_start ''club_start/:page'', :controller => ''clubs'', :action => ''start'' > > > > And if I link to it using the club_start_url, it will create a URL for: > > > > http://.../clubs/start > > > > Instead of the expected behavior of: > > > > http://.../club_start > > > > If I remove the :page parameter, it works as expected. Also, any > > forms on that clubs/start page that is rendered will automatically > > submit to the correct club_start URL, but they also include the :page > > parameter. > > > > Does this appear to be a valid bug? > > > Try this: > > map.club_start ''club_start/:page'', :controller => ''clubs'', :action => > ''start'', :page => nil > > If you''re using :page for pagination, you could also do this: > > map.club_start ''club_start/:page'', :controller => ''clubs'', :action => > ''start'', :page => ''1'' > > -- > rick > http://techno-weenie.net > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
Hi Rick, I appreciate your responses. However, I feel there is still one inconsistency that is not correct. Consider this example: If I have a named route as follows: map.magic ''magic/:trick'', :controller => ''hat'', :action => ''rabbit'' If I just say ''magic_url'', the URL in the browser will show ''hat/rabbit''. But if I set :trick => ''pull_out'', the URL in the browser will show ''magic/pull_out'' I would expect the case with no :trick set to just show ''magic'' in the URL, not the controller and action name. The named route is being used in both cases, so I would expect that if it shows the named route name for the one, it should show it for the other. Comments? Tom On 8/4/05, Rick Olson <technoweenie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On 8/4/05, Tom Davies <atomgiant-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > Thanks Rick. That is a reasonable workaround. > > > > However, the named routes behave inconsistently in that if you pass it > > the :page, it will show the named route name, and if you don''t it will > > show you the :controller/:action. I believe this may still be a bug, > > but since I have a workaround I can live with it. > > > > If anyone else feels this should be logged as an issue, please let me > > know and I will log something in Trac. Otherwise, I will just happily > > use the workaround. > > > > Thanks, > > Tom > > By not specifying a default value for :page, it thinks that just > giving it the controller and action name is not enough. I don''t > believe this is a bug by any means. Giving it the default value lets > it know that hey, you don''t absolutely need that page variable in the > URL. Also, if you use a default value of ''1'' and use page_url(:page > => ''1''), it knows to leave that off the generated route for you. > > Tom: sorry for the dupe email, I meant for this to go to the list :) > > -- > rick > http://techno-weenie.net > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
On 8/4/05, Tom Davies <atomgiant-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hi Rick, > > I appreciate your responses. However, I feel there is still one > inconsistency that is not correct. Consider this example: > > If I have a named route as follows: > map.magic ''magic/:trick'', :controller => ''hat'', :action => ''rabbit'' > > If I just say ''magic_url'', the URL in the browser will show ''hat/rabbit''. > > But if I set :trick => ''pull_out'', the URL in the browser will show > ''magic/pull_out'' > > I would expect the case with no :trick set to just show ''magic'' in the > URL, not the controller and action name. The named route is being > used in both cases, so I would expect that if it shows the named route > name for the one, it should show it for the other. > > Comments?I see your point. While I haven''t looked into how named routes work, I think it''s very similar to this (using missing_method however): def magic_url(options) url_for({:controller => ''hat'', :action => ''rabbit''}.merge(options)) end It''s just taking the options that follow the route''s options. Thats why a default is needed. This has been standard Routes behavior from day one. I imagine you''d have to parse the route string to find other params not mentioned, and set a default of nil for it. -- rick http://techno-weenie.net
On Thu, Aug 04, 2005 at 10:53:05AM -0400, Tom Davies wrote:> I appreciate your responses. However, I feel there is still one > inconsistency that is not correct. Consider this example: > > If I have a named route as follows: > map.magic ''magic/:trick'', :controller => ''hat'', :action => ''rabbit'' > > If I just say ''magic_url'', the URL in the browser will show ''hat/rabbit''. > > But if I set :trick => ''pull_out'', the URL in the browser will show > ''magic/pull_out'' > > I would expect the case with no :trick set to just show ''magic'' in the > URL, not the controller and action name. The named route is being > used in both cases, so I would expect that if it shows the named route > name for the one, it should show it for the other. > > Comments?That is not how Routes recognition, Named or unNamed, work. An route part is not optional unless a default value is explicitly given to it in the Route definition as was stated previously. Routes will not generate the custom route url unless it finds a complete match. If you want just magic to show up when you don''t pass any :trick in then you can add a route rule. Routes are evaluated from top to bottom and the first to match stops evaluation. That is why the :controller/:action route rule is listed last. map.magic_trick ''magic/:trick'', :controller => ''hat'', :action => ''rabbit'' map.magic ''magic'', :controller => ''hat'', :action => ''rabbit'' link_to ''Some trick'', magic_trick_url(:trick => ''pullout'') # => ''magic/pullout'' link_to ''Just magic'', magic_url # => ''magic'' marcel -- Marcel Molina Jr. <marcel-WRrfy3IlpWYdnm+yROfE0A@public.gmane.org>
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I am very new to all this, but I think I read something that could be related to this. I think you need to add a default for trick (as already indicated). That''s what you''d have to do if it wasn''t a namebased map at least. The map.connect documentation (with defaults to nil) are found here here: http://manuals.rubyonrails.com/read/chapter/65#page164 (example 2). Hope that helps, Ronny Rick Olson wrote:> On 8/4/05, Tom Davies <atomgiant-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > >>Hi Rick, >> >>I appreciate your responses. However, I feel there is still one >>inconsistency that is not correct. Consider this example: >> >>If I have a named route as follows: >> map.magic ''magic/:trick'', :controller => ''hat'', :action => ''rabbit'' >> >>If I just say ''magic_url'', the URL in the browser will show ''hat/rabbit''. >> >>But if I set :trick => ''pull_out'', the URL in the browser will show >>''magic/pull_out'' >> >>I would expect the case with no :trick set to just show ''magic'' in the >>URL, not the controller and action name. The named route is being >>used in both cases, so I would expect that if it shows the named route >>name for the one, it should show it for the other. >> >>Comments? > > > I see your point. While I haven''t looked into how named routes work, > I think it''s very similar to this (using missing_method however): > > def magic_url(options) > url_for({:controller => ''hat'', :action => ''rabbit''}.merge(options)) > end > > It''s just taking the options that follow the route''s options. Thats > why a default is needed. This has been standard Routes behavior from > day one. I imagine you''d have to parse the route string to find other > params not mentioned, and set a default of nil for it. >-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (MingW32) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org iD8DBQFC8jXnMRRzQX3ma+kRAmRZAKDZ5rmG77N6BG7fJADUIVRrSUZq/ACeNoC7 IHiCcgTN2P0/8N3rvWLK1ns=BMFD -----END PGP SIGNATURE-----
Hi Marcel, Thanks for joining the discussion :) Giving this some more thought, the only real issue I have is with the way the _url works in named urls For this route: map.magic_trick ''magic/:trick'', :controller => ''hat'', :action => ''rabbit'' If I call magic_trick_url with no parameters, it is generating a URL as ":controller/:action"; But it seems like it should either: A) result in an error since mandatory parameters were not passed to it. OR B) just insert nils for the parameters that don''t exist. A named URL should always be displayed using its ''name''. For the case of "hidden" controllers, it should never expose the controller that is accessed via a named URL. I am OK with explicitly specifying parameters, but I think the way it works no deserves some discussion. Tom On 8/4/05, Marcel Molina Jr. <marcel-WRrfy3IlpWYdnm+yROfE0A@public.gmane.org> wrote:> On Thu, Aug 04, 2005 at 10:53:05AM -0400, Tom Davies wrote: > > I appreciate your responses. However, I feel there is still one > > inconsistency that is not correct. Consider this example: > > > > If I have a named route as follows: > > map.magic ''magic/:trick'', :controller => ''hat'', :action => ''rabbit'' > > > > If I just say ''magic_url'', the URL in the browser will show ''hat/rabbit''. > > > > But if I set :trick => ''pull_out'', the URL in the browser will show > > ''magic/pull_out'' > > > > I would expect the case with no :trick set to just show ''magic'' in the > > URL, not the controller and action name. The named route is being > > used in both cases, so I would expect that if it shows the named route > > name for the one, it should show it for the other. > > > > Comments? > > That is not how Routes recognition, Named or unNamed, work. An route part is > not optional unless a default value is explicitly given to it in the Route > definition as was stated previously. Routes will not generate the custom > route url unless it finds a complete match. If you want just magic to show up > when you don''t pass any :trick in then you can add a route rule. Routes are > evaluated from top to bottom and the first to match stops evaluation. That is > why the :controller/:action route rule is listed last. > > map.magic_trick ''magic/:trick'', :controller => ''hat'', :action => ''rabbit'' > map.magic ''magic'', :controller => ''hat'', :action => ''rabbit'' > > link_to ''Some trick'', magic_trick_url(:trick => ''pullout'') > # => ''magic/pullout'' > > link_to ''Just magic'', magic_url > # => ''magic'' > > marcel > -- > Marcel Molina Jr. <marcel-WRrfy3IlpWYdnm+yROfE0A@public.gmane.org> > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
Thanks Ronny. That actually fixes it without having to pass values into every named *_url call. For example: map.magic_trick ''magic/:trick'', :controller => ''hat'', :action => ''rabbit'', :trick => nil works just fine. I still say a named route should always be named, or else it is not really a named route... but in the grand scheme of things, this is a minor issue. Thanks for all of the feedback. Tom On 8/4/05, Ronny Hanssen <ronnyh-7tg5dEkr+6sdnm+yROfE0A@public.gmane.org> wrote:> -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > I am very new to all this, but I think I read something that could be > related to this. I think you need to add a default for trick (as already > indicated). That''s what you''d have to do if it wasn''t a namebased map at > least. The map.connect documentation (with defaults to nil) are found > here here: > http://manuals.rubyonrails.com/read/chapter/65#page164 (example 2). > > Hope that helps, > Ronny > > Rick Olson wrote: > > On 8/4/05, Tom Davies <atomgiant-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > >>Hi Rick, > >> > >>I appreciate your responses. However, I feel there is still one > >>inconsistency that is not correct. Consider this example: > >> > >>If I have a named route as follows: > >> map.magic ''magic/:trick'', :controller => ''hat'', :action => ''rabbit'' > >> > >>If I just say ''magic_url'', the URL in the browser will show ''hat/rabbit''. > >> > >>But if I set :trick => ''pull_out'', the URL in the browser will show > >>''magic/pull_out'' > >> > >>I would expect the case with no :trick set to just show ''magic'' in the > >>URL, not the controller and action name. The named route is being > >>used in both cases, so I would expect that if it shows the named route > >>name for the one, it should show it for the other. > >> > >>Comments? > > > > > > I see your point. While I haven''t looked into how named routes work, > > I think it''s very similar to this (using missing_method however): > > > > def magic_url(options) > > url_for({:controller => ''hat'', :action => ''rabbit''}.merge(options)) > > end > > > > It''s just taking the options that follow the route''s options. Thats > > why a default is needed. This has been standard Routes behavior from > > day one. I imagine you''d have to parse the route string to find other > > params not mentioned, and set a default of nil for it. > > > -----BEGIN PGP SIGNATURE----- > Version: GnuPG v1.4.0 (MingW32) > Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org > > iD8DBQFC8jXnMRRzQX3ma+kRAmRZAKDZ5rmG77N6BG7fJADUIVRrSUZq/ACeNoC7 > IHiCcgTN2P0/8N3rvWLK1ns> =BMFD > -----END PGP SIGNATURE----- > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >