Use a partial form with form_for

I’m sure the cool kids know this already but it gave me a problem so I thought I’d post it.

When using “render :partial => ‘form’”, where ‘form’ is being rendered for a ‘new’ and edit ‘view’, you need to pass a local variable for your model object.

Originally I had

<% form_for :product, @product, :url => { :action => 'update', :id => @product.id } do |f| %>

<!--[form:product]-->
<div id='container'>
    <%= render :partial => 'form' %>
</div>

<button type="submit">Save Listing</button> 

and here’s the solution with ‘f’ passed as a local variable to the partial

<% form_for :product, @product, :url => { :action => 'update', :id => @product.id } do |f| %>

<!--[form:product]-->
<div id='container'>
    <%= render :partial => 'form', :locals => { :f => f } %>
</div>

<button type="submit">Save Listing</button> 
This entry was posted in Ruby on Rails. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

17 Comments

  1. Posted October 25, 2006 at 1:16 pm | Permalink

    I also think you can do something like render :partial => ‘form’, :o bject => f which is a few less characters (at least at one point I remember using that).

  2. Posted November 7, 2006 at 10:31 am | Permalink

    The ‘:object =>f’ syntax might be deprecated – http://api.rubyonrails.com/classes/ActionController/Base.html#M000206. The ‘:locals => { :f => f }’ thing definitely works.

    Thanks for posting this – guess I’m not cool either because I wasn’t sure how to use form_for and partials either.

  3. Posted November 21, 2006 at 7:52 am | Permalink

    Ah, makes sense. Thanks for checking.

  4. Justin Reagor
    Posted February 18, 2007 at 11:38 am | Permalink

    Ahhh… this makes sense now! Just passing your model as a local variable into your partial. Now the question is, why form_tag’s are still being used in scaffolds!

  5. Posted March 3, 2007 at 8:34 pm | Permalink

    Thanks… I was puzzled by this also and spent a few hours trying to figure out what I was doing wrong!
    – Another Uncool Ruby Kid

  6. Posted March 30, 2007 at 4:08 am | Permalink

    Why not do something like:

    ‘form’, :locals => { :form_action => :create } %>

    and put the form_for tag in the partial. If you need text for the button as well, you could pass that in.

  7. Wes Bailey
    Posted May 15, 2007 at 11:37 pm | Permalink

    I like Jun-Dai’s comment but the reason I think most people come across this problem is from the rails generated scaffold which produces a form_tag and people learn the magic of form_for and then render partial fails because in its local context it doesn’t know about the form. This post shows how to register the form in the local scope of the partial.

    Jun-Dai’s comment is really interesting as well because it goes along with the Rails Recipe of cleaning up the controller actions new, create, edit and update and consolidating them into 1 method.

  8. Posted June 15, 2007 at 6:34 pm | Permalink

    Passing the actual FormBuilder instance as a local is definitely the way to go.

  9. Posted January 18, 2008 at 8:35 am | Permalink

    We just applied a patch that allows you to do:

    f %>

    This will render the _form partial with a local variable called form referencing the FormBuilder.

    More info on http://elctech.com/2008/1/16/patching-rails-rendering-form-partials

  10. Posted February 28, 2008 at 5:10 am | Permalink

    I have a simple form, it has a text_field and a text_area. I want to add
    2 submit buttons. Each one will do a different action. I was thinking I
    could do form_for, and fields_for, but then I thought that fields_for is
    used for having two objects, but I only have one. I know I could just
    make them images, and links, but I suck at photoshop, and my boss is one
    of those people that feels he is a designer, and he tells me that I have
    to have some sort of flashing animated gif that is on the right hand
    side, and some link that has to be red over on the left side. He also
    told me I have to have two buttons, but I don’t know how to do that.

  11. Posted February 28, 2008 at 8:34 am | Permalink

    what about this solution http://www.myersds.com/notebook/2006/09/10/multiple_submit_buttons_on_a_form_with_rails

  12. Jason
    Posted March 25, 2008 at 5:09 pm | Permalink

    Excellent thanks for this tip I was trying to figure out the same thing!

    Jason

  13. Trevor
    Posted September 8, 2008 at 11:16 am | Permalink

    Awesome, this is a life-saver. Thanks for the post.

  14. Posted November 11, 2008 at 4:04 pm | Permalink

    Im completely new at this whole rails business, and while im really enjoying it im not really getting a lot. I see that this works well, but what is the :locals symbol saying?

  15. Posted November 11, 2008 at 10:23 pm | Permalink

    hey jason, :locals is enabling the partial ‘form’ to have access to the variable ‘f’ which is the form_for the model ‘product’

    so if the model :product has product.name and product.type etc then you can create form elements like

    f.text_field :name
    f.text_field :type

    and they will be bound to the :product model (ie if you are editing a product it’s current values will be set in the text inputs)

  16. Posted January 8, 2009 at 11:20 pm | Permalink

    jason’s comment is good.
    its not transparent how a partial works in conjunction with a form. OK you transmit the local but its a local how do you get the value back ? The submit is outside the partial. A partial seems to be something like a visual subprogram for html-things But not very transparent for me. As long as you are withing rails its works somehow with a magic. But you have to know the magic (like this)….

  17. Posted January 9, 2009 at 12:49 am | Permalink

    Hi playing around with this : Does anybody know how it work from an action ?
    I want to make dynamic forms the first field is entered from the user the field is observed : An observe_field calls an action and then depending on rules (a case in the action) different partials (or js.rjs) are called. What is then with the magic local ? Has anybody an idea ?

One Trackback

  1. [...] This was giving me problems. This solved it. [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word