I have a Wizard model that the client references w/o an ID (it’s saved in the session), so I’ve created a singular resource for :show and :update. I want the admin to have access to all instances of that model via index so admin can delete strays, so I’ve added a plural resources for :index and :destroy. The index and destroy works, but I can’t figure out the right arguments to pass to form_for in the update view.
The setup
# config/routes.rb
WTest::Application.routes.draw.do
resource :wizard, :only => [:show, :update]
resources :wizards, :only => [:index, :destroy]
...
end
resulting in
$ rake routes
wizards GET /wizards(.:format) {:action=>"index", :controller=>"wizards"}
wizard DELETE /wizards/:id(.:format) {:action=>"destroy", :controller=>"wizards"}
GET /wizard(.:format) {:action=>"show", :controller=>"wizards"}
PUT /wizard(.:format) {:action=>"update", :controller=>"wizards"}
This sets up routes the way I’d expect.
The question (revised since original post)
In the console:
>> app.wizard_path
raises the error ActionController::RoutingError: No route matches {:action=>"destroy", :controller=>"wizards"}
Why is this? Have I set up my routes incorrectly? I need to specify :url => wizard_path for form_for() in the wizards’s update view.
The details
If I specify an explicit path in my call to form_for:
# app/view/wizards/update.html.erb
<%= form_for @wizard, :url => wizard_path do |f| %>
<%= f.submit %>
<% end %>
… then attempting to render this for gets an error on the form_for line:
No route matches {:action=>"destroy", :controller=>"wizards"}
I have no idea why it’s trying to match the destroy action. How do I get the form to submit to the {action=>"update", :controller=>"wizards"} route?
(By the way, I looked at bug 267, and I don’t think it is the same as what I’m observing. But if it is this bug, is there a workaround?)
Carrying on the long tradition of answering my own questions (meh!), I think I figured it out. If my analysis is wrong, I’d be happy to give someone else the checkmark…
The cause of the problem
Look at the output of
rake routesThe path method ‘wizard_path’ is ambiguous: it can either refer to the DELETE clause, in which case it needs an :id argument (
wizard_path(22)), or it can refer to the GET and PUT clauses, in which case it doesn’t take an ID argument.The solution
So my solution was to create a route specifically for deletion. My revised
routes.rbfile now reads:and
rake routesnow produces:I needed to make a one-line change to the delete link in wizards/index.html.erb to use the new delete_wizard_path, but everything works now.