Skip to content
Browse files

Clarify fields_for and form builders

  • Loading branch information...
1 parent d9e6413 commit 32fee815faca79b7d1de33072bc55e7d0e08b453 @fcheung fcheung committed Jan 1, 2009
Showing with 32 additions and 13 deletions.
  1. +32 −13 railties/doc/guides/source/form_helpers.txt
View
45 railties/doc/guides/source/form_helpers.txt
@@ -582,9 +582,9 @@ File upload form
:multipart - If set to true, the enctype is set to "multipart/form-data".
Scoping out form controls with `fields_for`
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-------------------------------------------
-`fields_for` creates a form builder in exactly the same way as `form_for` but doesn't create the actual `<form>` tags. In that sense it creates a scope around a specific model object like `form_for`, which is useful for specifying additional model objects in the same form. For example we might a Person model with an associated ContactDetail model. We could create a form for editing both like so:
+`fields_for` creates a form builder in exactly the same way as `form_for` but doesn't create the actual `<form>` tags. It creates a scope around a specific model object like `form_for`, which is useful for specifying additional model objects in the same form. For example if you had a Person model with an associated ContactDetail model you could create a form for editing both like so:
-------------
<% form_for @person do |person_form| %>
<%= person_form.text_field :name %>
@@ -593,26 +593,47 @@ Scoping out form controls with `fields_for`
<% end %>
<% end %>
-------------
+
which produces the following output:
+
-------------
<form action="/people/1" class="edit_person" id="edit_person_1" method="post">
<input id="person_name" name="person[name]" size="30" type="text" />
<input id="contact_detail_phone_number" name="contact_detail[phone_number]" size="30" type="text" />
</form>
-------------
-Making custom form builders
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-You can also build forms using a customized FormBuilder class. Subclass FormBuilder and override or define some more helpers, then use your custom builder. For example, let’s say you made a helper to automatically add labels to form inputs.
+Form builders
+-------------
+
+As mentioned previously the object yielded by `form_for` and `fields_for` is an instance of FormBuilder (or a subclass thereof). Form builders encapsulate the notion of displaying a form elements for a single object. While you can of course write helpers for your forms in the usual way you can also subclass FormBuilder and add the helpers there. For example
-----------------------------------------------------------------------------
-<% form_for :person, @person, :url => { :action => "update" }, :builder => LabellingFormBuilder do |f| %>
+----------
+<% form_for @person do |f| %>
+ <%= text_field_with_label f, :first_name %>
+<% end %>
+----------
+can be replaced with
+----------
+<% form_for @person, :builder => LabellingFormBuilder do |f| %>
<%= f.text_field :first_name %>
- <%= f.text_field :last_name %>
- <%= text_area :person, :biography %>
- <%= check_box_tag "person[admin]", @person.company.admin? %>
<% end %>
-----------------------------------------------------------------------------
+----------
+by defining a LabellingFormBuilder class similar to the following:
+-------
+class LabellingFormBuilder < FormBuilder
+ def text_field attribute, options={}
+ label(attribute) + text_field(attribute, options)
+ end
+end
+-------
+If you reuse this frequently you could define a `labeled_form_for` helper that automatically applies the `:builder => LabellingFormBuilder` option.
+
+The form builder used also determines what happens when you do
+------
+<%= render :partial => f %>
+------
+If `f` is an instance of FormBuilder then this will render the 'form' partial, setting the partial's object to the form builder. If the form builder is of class LabellingFormBuilder then the 'labelling_form' partial would be rendered instead.
* `form_for` within a namespace
@@ -630,8 +651,6 @@ time_zone_options_for_select(selected = nil, priority_zones = nil, model = ::Act
time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {})
----------------------------------------------------------------------------
-Form builders
--------------
== Changelog ==

0 comments on commit 32fee81

Please sign in to comment.
Something went wrong with that request. Please try again.