views:

178

answers:

2

When submitting a form to create a new object i get an error message when submitting the form. When i use the same form but then with an instance variable everything seems to go fine, any clue why the submit with the :symbol fails?

The error message says: Only get, put, and delete requests are allowed.

The code for the new form with :symbol is:

<% form_for :ecard do |f| %>
 <%= label(:ecard, :title) %><br/>
 <%= f.text_field :title, :tabindex => "1" %>
 <%= f.submit "Create Ecard" %>
<% end %>

The form goes ok when i use

<% form_for @ecard do |f| %>
 <%= label(:ecard, :title) %><br/>
 <%= f.text_field :title, :tabindex => "1" %>
 <%= f.submit "Create Ecard" %>
<% end %>

Some code out of my controller:

# GET new_ecard_url
# return an HTML form for describing the new ecard
def new
 @ecard = Ecard.new
end

# POST ecard_url
def create
 # create an ecard
 @ecard = Ecard.new(params[:ecard])
 if @ecard.save
  flash[:notice] = "Succesfully created a new Ecard"
  redirect_to :action => 'index'
 else
  flash[:warning] = "Error when saving Ecard"
  render :action => 'new'
 end
end
+1  A: 

If the first argument is a symbol, it describes the object the form is about and name the instance variable, and then you need to provide the URL.

The actual object can be used and then it will use your routes to try and determine the URL. This means that it must know of a *new_ecard_path* and *edit_ecard_path*.
It will look at the object and see if it is a new record to determine which to use.

If you are using resource routes with the default restful routes, then you can probably just use the instance object. If you need to specify the URL that the form goes to, then use the symbol and specify the URL.

There are a few examples at http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html

danivovich
So the use of <% form_for :ecard do |f| %> is actually incomplete as i read your reply?
Marco
A: 

A good way to see what's going on is to use Firebug and inspect the generated HTML. If you don't have Firebug, get it now, it's really invaluable.

If you create your form using the instance variable, you'll get something along the lines of:

<form id="new_ecard" class="new_ecard" method="post" action="/ecards">

So this will create a POST request to the /ecards action, which is the create method (by the way, your comment above the create method should be POST ecards_url, not ecard_url, unless you've defined it otherwise).

However if you only use the :ecard symbol instead of the instance variable, you'll get:

<form method="post" action="/ecards/new">

Since you haven't specified a URL, it uses the current one. This means your form will call itself in this case, and nothing will happen.

All this is due to all the so called magic Rails does - convention over configuration. But as danivo said, you can specify the URL manually and explicitly state each parameter for the form if you do not want to have this magic happen for you.

JRL
Things are clearing for me :) I was getting confused by tutorials that where using only the :card symbol and i was actually wondering why that did not work for me. So the suggestion is the use the normal instance variable instead of the symbol notation. This offcourse when i hold myself to the convention and that is something is surely want to do :)
Marco