Unknown action in Rails App

Hi,

I'm following a tutorial which creates a rails project using the scaffolding generator (in Rails 2.3.8). One of the exercises at the end of this tutorial is to put the form used in the scaffolding's "new" and "update" views into a partial.

So, I created a file "_form.html.erb" in the views folder of my app.

In "new.html.erb" I call the partial thus: <%= render :partial => "form", :locals => {:url => {:action => "create"} %>

This works as it should and I have no problems creating a new dataset.

In "edit.html.erb" I wrote this: <%= render :partial => "form", :locals => {:url => {:action => "update", :id => @flight.id}} %>

but when I try to update an existing record I get the error:

Unknown action No action responded to 11. Actions: create, destroy, edit, index, new, show, and update

(where 11 is the id or the object I am trying to update)

Using Firebug to check where the form is being sent, I see: <form method="post" action="/flights/11">

When I run "rake routes" I see: PUT /flights/:id(.:format) {:controller=>"flights", :action=>"update"}

What am I missing? Can anyone point me in the right direction? Thanks very much in advance.

When I run "rake routes" I see: PUT /flights/:id(.:format) {:controller=>"flights", :action=>"update"}

What am I missing? Can anyone point me in the right direction? Thanks very much in advance.

because a route isn't just a path, it's also an HTTP method. In the case of update the method is PUT (browsers don't let forms use methods other than POST or GET but rails lets you simulate the extra methods by adding a form parameter). You may be overcomplicating things - if you do form_for @flight ... rails will pick the right path & method for you ( based on whether the record is a new record or not)

Fred

Cheers for the explanation, Fred. Following your advice I passed the appropriate HTTP method to the form in the partial and now everything works as it should.

In case it helps anyone else, I now have:

new.html.erb: <%= render :partial => "form", :locals => {:url => {:action => "create"}, :method => :post} %>

edit.html.erb: <%= render :partial => "form", :locals => {:url => {:action => "update", :id => @flight}, :method => :put} %>

_form.html.erb: <% form_for :flight, :url => url, :html=>{:method=> method} do |f| %>

Thanks again.

Jim Burgess wrote in post #968051:

Cheers for the explanation, Fred. Following your advice I passed the appropriate HTTP method to the form in the partial and now everything works as it should.

In case it helps anyone else, I now have:

new.html.erb: <%= render :partial => "form", :locals => {:url => {:action => "create"}, :method => :post} %>

edit.html.erb: <%= render :partial => "form", :locals => {:url => {:action => "update", :id => @flight}, :method => :put} %>

_form.html.erb: <% form_for :flight, :url => url, :html=>{:method=> method} do |f| %>

But you missed Fred's point entirely: you don't need to do that! Rails will test @flight.new_record? and pick the method accordingly. So all you need in both new.html.erb and edit.html.erb is render :partial => 'form' and in _form.html.erb, just form_for @flight

You're reinventing what Rails already does for you.

Thanks again.

Best,

But you missed Fred's point entirely

Oops, it appears I did.

So all you need in both new.html.erb and edit.html.erb is render :partial => 'form' and in _form.html.erb, just form_for @flight

Yup, that works embarrassingly well! Thanks a lot for pointing that out.