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> 

13 Responses to “Use a partial form with form_for”

  1. John Nunemaker Says:

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

  2. Rich Says:

    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. John Nunemaker Says:

    Ah, makes sense. Thanks for checking.

  4. Justin Reagor Says:

    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. Nola Stowe Says:

    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. Jun-Dai Says:

    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 Says:

    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. Duncan Beevers Says:

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

  9. Damian Janowski Says:

    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. plastik Says:

    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. Alastair Says:

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

  12. Jason Says:

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

    Jason

  13. Scott Motte » Blog Archive » How to put a partial form in form_for Says:

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

Leave a Reply

*
To prove you're a person (not a spam script), type the security word shown in the picture.
Anti-Spam Image