This project is archived and is in readonly mode.
Routing breakage in 3.0.3
-
Wincent Colaiuta
One minor correction to what I wrote above. The route is actually visible in the
rake routesoutput:issues GET /issues/page/:page(.:format) {:action=>"index", :controller=>"issues", :page=>/\d+/} GET /issues(.:format) {:action=>"index", :controller=>"issues"} POST /issues(.:format) {:action=>"create", :controller=>"issues"} new_issue GET /issues/new(.:format) {:action=>"new", :controller=>"issues"} edit_issue GET /issues/:id/edit(.:format) {:action=>"edit", :controller=>"issues"} issue GET /issues/:id(.:format) {:action=>"show", :controller=>"issues"} PUT /issues/:id(.:format) {:action=>"update", :controller=>"issues"} DELETE /issues/:id(.:format) {:action=>"destroy", :controller=>"issues"}Here's a quick test demo in Rails console of how this blows up:
>> include Rails.application.routes.url_helpers => Object >> issues_path ActionController::RoutingError: No route matches {:controller=>"issues"} -
Wincent Colaiuta
For comparison, the output of
rake routesunder Rails v3.0.1:issues GET /issues/page/:page(.:format) {:page=>/\d+/, :controller=>"issues", :action=>"index"} issues GET /issues(.:format) {:controller=>"issues", :action=>"index"} issues POST /issues(.:format) {:controller=>"issues", :action=>"create"} new_issue GET /issues/new(.:format) {:controller=>"issues", :action=>"new"} edit_issue GET /issues/:id/edit(.:format) {:controller=>"issues", :action=>"edit"} issue GET /issues/:id(.:format) {:controller=>"issues", :action=>"show"} issue PUT /issues/:id(.:format) {:controller=>"issues", :action=>"update"} issue DELETE /issues/:id(.:format) {:controller=>"issues", :action=>"destroy"} -
Andrés Mejía
I think this is the intended behavior, and not a bug:
When you say
you are saying that aget 'page/:page' => 'issues#index', :page => %r{\d+}pageparameter is required. If you pass thepageparameter it works as expected:ruby-1.9.2-p0 > issues_path(:page => 666) => "/issues/page/666"If you want the
pageparameter to be optional, doget '(page/:page)' => 'issues#index', :page => %r{\d+}This makes it work as you want:
ruby-1.9.2-p0 > issues_path => "/issues" ruby-1.9.2-p0 > issues_path(:page => 1) => "/issues/page/1" ruby-1.9.2-p0 > issues_path(:page => 666) => "/issues/page/666"Maybe the bug was on Rails 3.0.1 that didn't enforce the presence of the
pageparameter? -
Wincent Colaiuta
Thanks, I'll apply that as a workaround for now.
As for whether it's intended or not, I don't know. It would be good to have clarification from one of the people who designed the router.
I always thought the basic idea in the routing file was that rules would have a kind of top-down precedence, so whatever gets declared first and can match, wins. So declaring the "page" rule after the non-paged case was consistent with that idea:
ie. the non-paged case would be the default which would usually apply, but in the presence of a page parameter the more specific paged case would apply
-
Andrés Mejía
By the way, it's not working properly for me on Rails 3.0.1, either:
On
routes.rb:resources :issues do collection do get 'page/:page' => 'issues#index', :page => %r{\d+} end endThis is what I get:
$ rails c Loading development environment (Rails 3.0.1) ruby-1.9.2-p0 > include Rails.application.routes.url_helpers => Object ruby-1.9.2-p0 > issues_path => "/issues" ruby-1.9.2-p0 > issues_path(:page => 666) => "/issues?page=666"So as you see, the it didn't use the
page/:pageroute.Do you get the same?
-
Wincent Colaiuta
I do, but I don't generate the page links using the helper in my app; I have an lib module that does that (via string concatenation, gasp)...
-
Andrés Mejía
All right. I think there's nothing to fix here. Can you change this ticket's state to "invalid"?
-
Wincent Colaiuta
Don't think I'm the one to do that, as I'm not sure that it is invalid. Better for someone from the core team, or someone more heavily involved in the router design, to make that decision.
-
Prem Sichanugrist (sikachu)
- State changed from new to open
- Assigned user set to Prem Sichanugrist (sikachu)
- Importance changed from to Low
Hi,
I can confirm that the behavior has been changed. That commits were making sure that no duplicate named route should be created. That's why in 3.0.3 you would see
issuesonly appearing on the first line.However, I think there's a bug here. It seems like
get 'page/:page' => 'issues#index', :page => %r{\d+}got added as a named route, which shouldn't be. I'll make a failing test case and a patch for it :)Thank you for reporting in. Meanwhile, I think you can solve your problem by adding
:asto your route like this:resources :issues do collection do get 'page/:page' => 'issues#index', :page => %r{\d+}, :as => 'issues_page' end end -
Prem Sichanugrist (sikachu)
- Importance changed from Low to Medium
-
José Valim
Prem is right, Rails in fact tries to generate routes automatically, but in this case it is generating the wrong one.
-
Repository
- State changed from open to resolved
(from [731ca00b484379661786fac36c17db7e085603c4]) Dynamically generaeted helpers on collection should not clobber resources url helper [#6028 Routing breakage in 3.0.3 state:resolved] https://github.com/rails/rails/commit/731ca00b484379661786fac36c17d...
-
Repository
(from [7e903a3d3a661c6ed4164d6a563bcf54e4497db3]) Dynamically generaeted helpers on collection should not clobber resources url helper [#6028 Routing breakage in 3.0.3 state:resolved] https://github.com/rails/rails/commit/7e903a3d3a661c6ed4164d6a563bc...
-
Wincent Colaiuta
Thanks for the fix.