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.