I have a city form that works for the initial creation of the city, but when I try to update the city, I get a routing error.
My routes.rb:
map.resources :states do |state|
state.resources :cities
end
The form:
<% simple_form_for @city, :url => state_cities_path do |f| %>
<%= f.input :name %>
<%= f.input :active %>
<%= f.submit "Save City" %>
<% end %>
The controller:
if @city.update_attributes(params[:city])
format.html { redirect_to 开发者_JS百科state_cities_path(:state_id => @city.state_id) }
format.xml { head :ok }
The error:
No route matches "/states/1/cities"
Now, if I click in the address bar, and hit enter, it takes me right to the route it says doesn't exist. The create action has an identical redirect_to.
Ideas? Is this a problem of POST vs PUT?
the problem is arround this line
simple_form_for @city, :url => state_cities_path
you are not letting the form builder create the proper route you are forcing it. Form builder creates a proper route for the instance you pass by detecting if is a new record,it then sets the proper path in the action attribute of the html form and sets the correct http method.
Seems that you got confused by the fact you are using nested routes and are trying pass the path/url, so the form builder is no longer detecting anything and is letting you set everything, since forms are post by default and you are passing the url to the create action it never matches to the update action. You are only mapping to the create action because the update action requires an ID like this
PUT /states/:state_id/cities/:id
that there is what is needed to match the update route, but you are not passing the id nor the http method.
Solution?
Let the form builder create the path, this is done with nested routes by passing an array with the parent instance and the child instance you want the form builder to use.
simple_form_for [@state,@city] do |f|
dont forget to put a value into @state or it will raise a nil error.
now the form builder should properly build the correct path for the create and update action.
by the way you can also redirect to an array like this
redirect_to [@state,@city]
it will send the user to the show action of the city.
精彩评论