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.

Routing error for restful resource under namespace

#4884

There seems to be some issues with the routing for resources under a namespace. I have tried this on both Rails 3b3 and 3b4 and both failed:

View code:

<%= form_for @notebook, :url => toggle_app_notebook_path(@notebook), :remote => true do |form| %>
    <%= submit_tag 'Toggle' %>
<% end %>

routes.rb:

namespace :app do

resources :notebooks do
  member do
    get :toggle  # get always works
    post :toggle # Post returns 404
  end
end

end

rake routes generate this:

                                  GET    /app/notebooks/:id/toggle(.:format)                                      {:controller=>"app/notebooks", :action=>"toggle"}
              toggle_app_notebook POST   /app/notebooks/:id/toggle(.:format)                                      {:controller=>"app/notebooks", :action=>"toggle"}

While GET requests work as expected, the POST always failed with a 404 error:

No route matches "/app/notebooks/1/toggle

To get this route to work correctly, I have to declare another matcher outside the resources :notebooks but still under the namespace, and the URL would be recognized correctly:

namespace :app do

match 'notebooks/:id/toggle' => 'notebooks#toggle'
resources :notebooks do
  member do
    get :toggle  
    post :toggle
  end
end

end

I'm on ruby-1.8.7-p249

(edit 1: update formatting)

Reported by Alex Le · June 17th, 2010 @ 02:47 AM

State: invalid
Milestone: none
Assigned to: nobody
Importance: Low

Activity

  1. Andrew White
    Andrew White

    It's because the form_for tag is setting the HTTP method to PUT since it thinks it's editing the notebook model instance. Add :html => { :method => :post } to the form_for tag and it works.

    June 17th, 2010 @ 07:07 AM

  2. Alex Le
    Alex Le

    Andrew, thanks a bunch. I have updated my code and your suggestion worked for me. I saw the PUT in the sever log but it didn't ring a bell for me, since the "rake routes" shows that the path is POST so I did not pay too much attention to the generated form code.

    I still think this is a bug, because member methods should be regular POST's, not PUT's. At least this was the way Rails 2.x would work (please correct me if I'm wrong)

    June 17th, 2010 @ 08:01 AM

  3. Andrew White
    Andrew White

    Alex, the form_for code doesn't look at routes when building the form tag - it justs sees an existing record and assumes that you're editing the object which is obviously a HTTP PUT with RESTful routes. You could argue that your toggle method should be a PUT since it's a specific case of editing a record.

    This is exactly the same as in 2.x.

    June 17th, 2010 @ 11:14 AM

  4. Rohit Arondekar
    Rohit Arondekar

    Alex, has Andrew cleared your issue? Can I close this ticket?

    June 17th, 2010 @ 03:08 PM

  5. DHH
    DHH
    • State changed from new to invalid

    June 17th, 2010 @ 03:35 PM

  6. Alex Le
    Alex Le

    Thanks for clearing up the confusion. Please go ahead and close the issue.

    June 17th, 2010 @ 04:46 PM