Help with custom FormBuilder

Josh,

I've spent a bit of time with custom form builders. I originally
started with help from the cookbook, but later branched out on my own,
almost rewriting many of the field helpers to fit exactly what I
wanted the output to be.

Now, I don't see where in your code you're handling your own
belongs_to helper, but I imagine it just does some processing to get
the list of options and calls the select helper. The idea is to
manipulate the options rather than simply passing them on as-is.
Inspect args from the end (args.last) and see if it's a hash. If so,
those are your options (and if not, no options were supplied). The
important thing to remember is that you want to manipulate the args,
passing some of them on to html_surround and keeping them from the
form helper (e.g. select). This means you have to provide explicit
arguments to super. (Otherwise, the parent class's method will be
called with the original arguments.)

So take

html_surround(label, super)

and change it to

# manipulation goes here
html_surround(label, super(arguments_for_super),
options_for_html_surround)

The select helper is a little trickier than the rest because it has
two sets of options ('options' and 'html_options') where the rest only
have one.

Josh,

About knowing the ID of the form element, there are methods in Action
Pack for that. I can't recall them off the top of my head, and to be
honest, some of my immense form builder bypassed and provided its own
IDs, so I knew exactly what was going on. But look for something like
"assign_default_name_and_id" and you'll see what's going on.

As for your Array#merge problem, if I'm not mistaken it's just that
you're calling super(label, args) instead of super(label, *args). See
this:

def args_length(*args)
  args.length
end

def blah(arg1, *args)
  args_length(args)
end

blah('test')
=> 1
blah('test', 1, 2, 3, 4)
=> 1

def blah(arg1, *args)
  args_length(*args)
end

blah('test')
=> 0
blah('test', 1, 2, 3, 4)
=> 4

And there's one thing that jumps out at me. You've changed it so
you're calling super for your brand-new association methods
(has_and_belongs_to_many, belongs_to), but the parent class doesn't
have them (I assume).