In revamping AssociationFu, I've discovered a woeful lack of knowledge around the Rails render engine. How does forms_for and fields_for work?
BTW, this is for Rails 2.0.2.
So here's how forms_for works:
Step one:
It determines the object name, making it singlular and underscored. If the first argument to forms_for is an object or an array:
It determines the following options (unless they have already been set by the options argument) based on the supplied object (which, in the case of an array, is the last element in the array):
- :html => {:class, :id, :method}
- :url
It then prepends the args array with the object.
Step two:
It concats (outputs text to the view) the tag.
Okay, that was nice and simple. Now for fields_for:
Also raises an exception if a block is not provided.
Step one:
Similar to form_for, determine the object_name (singular, underscore). If an array, it determines the form options identically to form_for {:html => {:class, :id, :method}, :url}.
Step two:
Here's why custom form_builders work. The builder class_id is derived from either options[:builder] or defaults to ActionView::Base.default_form_builder.
Step three:
The supplied block is yielded and passed an instance of the builder, which is initialized with the object_name, object, self (ActionView object or "template"), options and the block).
Crazy. So what does builder do?
Here's how builder works:
Any instance of FormBuilder initializes instance variables:
@object_name
@object
@template (the ActionView instantiation)
@options
@proc (the block)
It then defines methods on itself for each of the field_helpers from the FormHelper class. It does this so it can pass the object_name, method (the field name) and object as options[:object].
Funny, but FormBuilder defines its own #fields_for method.
Sunday, June 1, 2008
Subscribe to:
Post Comments (Atom)
1 comments:
Hi Kevin! Yes, the fields_for method in FormBuilder does some clever things with the structure of the params hash. Have a look at this to see how this is useful.
This has tidied up one of my controllers no end, but I now need to fix my custom FormBuilder to have a custom fields_for...
Post a Comment