Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Inappropriate route

#4440

Hello,

In my rails 3 application, I have the following routes.rb :

App::Application.routes.draw do |map|
    scope '/:lang' do
        scope '/:category_id' do
            root :to => 'categories#show', :as => :category
        end
        root :to => 'categories#index'
    end
    resources :categories, :except => [:index, :show]
    root :to => 'main#pick_locale'
end

The rake routes method generates the urls as I'd expect them to be :

/:lang/:category_id            {:controller=>"categories", :action=>"show"}
/:lang                         {:controller=>"categories", :action=>"index"}
categories POST   /categories(.:format)          {:controller=>"categories", :action=>"create"}
new_category GET    /categories/new(.:format)      {:controller=>"categories", :action=>"new"}
             PUT    /categories/:id(.:format)      {:controller=>"categories", :action=>"update"}
category DELETE /categories/:id(.:format)      {:controller=>"categories", :action=>"destroy"}
edit_category GET    /categories/:id/edit(.:format) {:controller=>"categories", :action=>"edit"}
root        /                              {:controller=>"main", :action=>"pick_locale"}

However when I use url_to(@category), it generates the following url :

categories/test?lang=en

Instead, of course, of :

en/test

When I go to this url generated, categories#show is being called. If I go to the expected url, the action is called too.

However if I remove the root :to => 'categories#show' call, none of the two urls are valid anymore.

Reported by Damien MATHIEU · April 19th, 2010 @ 06:09 PM

State: invalid
Milestone: 3.0.2
Assigned to: José Valim José Valim
Importance: Low

Activity

  1. Damien MATHIEU
    Damien MATHIEU

    I've written a test that should fail with that (see attached).
    However it seems in edge it works fine.
    The tests I made yesterday were on beta3 (I know I should have tested on edge). I'll test it deeper with edge.

    April 20th, 2010 @ 08:40 AM

  2. Damien MATHIEU
  3. Damien MATHIEU
    Damien MATHIEU

    FYI even though the test goes well, I still get the same in my application.

    April 20th, 2010 @ 09:03 AM

  4. Jeremy Kemper
    Jeremy Kemper
    • Milestone cleared.
    • State changed from new to open
    • Assigned user set to josh

    April 22nd, 2010 @ 02:28 AM

  5. Jeremy Kemper
  6. José Valim
    José Valim

    Can you please provide a failing test case on master then?

    April 22nd, 2010 @ 08:13 AM

  7. Damien MATHIEU
    Damien MATHIEU
    • Assigned user cleared.

    As said before, I couldn't reproduce it in a test. And that's for a very simple reason. It's a mistake from my side on the application, not from rails.

    April 22nd, 2010 @ 08:44 AM

  8. José Valim
    José Valim
    • Assigned user set to José Valim

    When you do "url_for(@category)", it's going to generate "category_url" based on the @category resource given. category_url will then generate "/categories/test" which becomes "/categories/test?lang=en" with the extra lang parameter.

    This can be verified if we look to the rake:route output you gave to us:

    category DELETE /categories/:id(.:format)      {:controller=>"categories", :action=>"destroy"}
    

    In other words, to have the behavior you expect, category_url should point to "/:lang/:category_id". You can try the following definition:

    scope '/:lang' do
      match ':category_id', :to => 'categories#show', :as => :category
      root :to => 'categories#index'
    end
    

    Just then category_url is going to point to the route you expect. If not, we may have a routes bug.

    April 22nd, 2010 @ 08:58 AM

  9. Damien MATHIEU
    Damien MATHIEU

    I didn't do a match for categories#show because I have other routes belonging to the category.
    In fact the problem was just because of routing priorities with the resources. Now that I define them before the lang scope, it works well.

    April 22nd, 2010 @ 09:02 AM

  10. José Valim
    José Valim
    • State changed from open to invalid

    Sweet! Can you post your new routes just as reference for other ppl? Thanks!

    April 22nd, 2010 @ 09:04 AM

  11. Damien MATHIEU
    Damien MATHIEU

    Yeah of course.
    I've decided to move the admin pages to a scope too. So in the end, I get the following :

    scope '/me' do
        resources :pages, :except => [:index, :show]
        resources :categories, :except => [:index, :show]
    end
    
    scope '/:lang' do
        scope '/:category_id' do
            match ':id' => 'pages#show', :as => :public_page
            root :to => 'categories#show', :as => :public_category
        end
        root :to => 'pages#index', :as => :locale
    end
    
    root :to => 'main#pick_locale'
    

    April 22nd, 2010 @ 09:22 AM

  12. Jeremy Kemper
    Jeremy Kemper
    • Milestone set to 3.0.2
    • Importance changed from to Low

    October 15th, 2010 @ 11:01 PM