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.