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| %>
<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| %>
<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. or leave a trackback:
Trackback URL.
17 Comments
I also think you can do something like render :partial => ‘form’,
bject => f which is a few less characters (at least at one point I remember using that).
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.
Ah, makes sense. Thanks for checking.
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!
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
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.
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.
Passing the actual FormBuilder instance as a local is definitely the way to go.
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
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.
what about this solution http://www.myersds.com/notebook/2006/09/10/multiple_submit_buttons_on_a_form_with_rails
Excellent thanks for this tip I was trying to figure out the same thing!
Jason
Awesome, this is a life-saver. Thanks for the post.
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?
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)
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)….
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
[...] This was giving me problems. This solved it. [...]