There is surprisingly little up to date information about ActionView::Helpers::FormBuilder. That's because mostly it hasn't changed. I'm always afraid of documentation going back to 2008 when we're talking about Rails because 99% of the time its just not quite going to work.
A little bit of background: we're using Twitter's Bootstrap in our project. There's a bit of ceremony around each field such that you need to do a .clearfix div, then a label, then a .input div and finally the input. I want to eliminate all those keystrokes so I can just do:
#./app/views/c2dm/new.html.haml
form_for @message, :url => {:action => 'create'} do |f|
%fieldset
= f.text_field :registration_id
= f.text_field :collapse_key
= f.text_area :message
.actions
%input.btn.primary{:type=>"submit"}
Here's the no-nonsense way of achieving this by adding a new class to your app/helpers/application_helper.rb (don't forget to restart your Rails server when you do this):
#./app/helpers/application_helper
⋮
# add these lines after the ApplicationHelper module
class BootstrapFormBuilder < ActionView::Helpers::FormBuilder
helpers = field_helpers +
%w{date_select datetime_select time_select} +
%w{collection_select select country_select time_zone_select} -
%w{hidden_field label fields_for} # Don't decorate these
helpers.each do |name|
define_method(name) do |field, *args|
options_index = ActionView::Helpers::FormBuilder.instance_method(name.to_sym).parameters.index([:opt,:options])
if options_index.nil?
options = args.last.is_a?(Hash) ? args.pop : {} # pretty sure this shouldn't happen
else
options = args[options_index - 1] # -1 to account for the method name argument
end
label = label(field, options[:label], :class => options[:label_class])
@template.content_tag(:div, :class => 'clearfix') do
@template.concat(label)
@template.concat(@template.content_tag(:div, :class => 'input') { @template.concat(super(field, *args)) })
end
end
end
end
ActionView::Base.default_form_builder = BootstrapFormBuilder
# you can also register this in ./config/application in the config block
# but I was not having a lot of success going that way
# which is why I moved it to the ./app/helpers/application_helper.rb file
Ideally you'd add this somewhere outside of application_helper.rb and load it properly.
What I referenced:
advanced rails studio: custom form builder
Form Builders in Rails
Working With and Around FormBuilder
Updated: 12/21/2011 for handling methods where options isn't the last param.