Question regarding form_for

Hello,

in my application, I have a new action inside of a controller. I also
have a view called new.rhtml which contains a form constructed using
the form_for method. In the controller's new action I have an instance
variable called @story which I assign a new Story object (Story is my
model) like so:

@story = Story.new(params[:story])

I use form_for like so:

form_for :story ...

If I change :story to let's say :abc in both instanced, it still
works. However, my book says I have to call it :stories so it
"properly maps with the @story object". Well, this obviously isn't the
case here, as it still works.

Can someone maybe explain it to me?

chell

When you say it works, do you mean that the form still displays or
that the data actually gets saved when you post the form. If the
later, then it would be good to see the rest of your form code to
answer your question.

If it's just that the form is still displayed, then this is just
because the form helper is not exactly 'linked' to the @story
variable. :story just tells the form helper to firstly, name the
fields correct (story[name]) and secondly, to put any attributes for
an existing @story variable in the correct fields. When you put :abc,
the form helper will look for @abc, see there isn't one and display
the form normally.

Hope that helps,

Steve

It actually still saves the data! Here's the controller:

class StoryController < ApplicationController
  def index
    @story = Story.find(:first, :order => 'RAND()')
  end
  def new
    @story = Story.new(params[:abc])
    if request.post?
      @story.save
      redirect_to :action => 'index'
    end

  end
end

And here's the form itself:

<% form_for :story do |f|%>
<p>
  name: <br />
  <%= f.text_field :name%>
</p>
<p>
  link: <br />
  <%= f.text_field :link%>
</p>
<p>
  <%= submit_tag%>
</p>
<% end %>

Oh sorry,

the form's actually:

<% form_for :abc do |f|%>
<p>
        name: <br />
        <%= f.text_field :name%>
</p>
<p>
        link: <br />
        <%= f.text_field :link%>
</p>
<p>
        <%= submit_tag%>
</p>
<% end %>

Ok - that's fine. As I said, it's not that :story links the form to
the @variable - it's that it sets the form field names up correctly.
As you've used params[:abc] in the controller, it'll pick up the data
fine.

For example:
<%= text_field :story, :name %>

will produce:

<input type="text" name="story[name]" />

which will map to:

params[:story][:name]

When you put :abc in, it's just another name for the fields.

The one thing you wont get is mapping of any data in @story mapped to
the fields when you edit:

With:
<%= text_field :story, :name %>

Rails will try and find the instance variable @story and the attribute
@story.name and put it in the value of the text field. If you
put :abc, Rails will look for @abc and find nothing. It wont fail, but
you wont see any of the story values in the form.

I guess this is just about getting your head round how forms are
submitted and picked up server-side. I hope this has made it a bit
clearer.

Steve

It might also be worth noting this form of the form_for:

<% form_for :abc, @story do |f|%>
...
...
...

This should link the :abc params up to the @story instance variable,
and should fix the issues with the update field mapping.