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).