Took a few days, but I ended up stumbling on the correct syntax. I hope this saves someone else's sanity!
Ruby return automagic, combined with the complex Rails scope at different times, made me disconnect. In particular, @template.text_field draws content, but it must be returned by a helper method in order to appear inside the calling block. However, we must return the results of two calls ...
def text_field(method, options={}) field_errors = object.errors[method].join(', ') if !@object.errors [method].blank? content = super content << (@template.content_tag(:span, @object.errors.full_messages_for(method), class: 'help-block') if field_errors) return content end
We must return the results of both the parent method (via super ) and our custom @template.content_tag(:span, injection. We can shorten this a bit using the Ruby plus + operator, which combines the return results.
def text_field(method, options={}) field_errors = object.errors[method].join(', ') if !@object.errors [method].blank? super + (@template.content_tag(:span, @object.errors.full_messages_for(method), class: 'help-block') if field_errors) end
Note. the form was initiated by an ActiveModel, so we have access to @object . Implementing form_for without linking it to the model will require you instead of text_field_tag .
Here is my finished custom FormBuilder
class BootstrapFormBuilder < ActionView::Helpers::FormBuilder def form_group(method, options={}) class_def = 'form-group' class_def << ' has-error' unless @object.errors[method].blank? class_def << " #{options[:class]}" if options[:class].present? options[:class] = class_def @template.content_tag(:div, options) { yield } end def text_field(method, options={}) field_errors = object.errors[method].join(', ') if !@object.errors [method].blank? super + (@template.content_tag(:span, @object.errors.full_messages_for(method), class: 'help-block') if field_errors) end end
Remember to say form_for !
form_for(:user, :builder => BootstrapFormBuilder [, ...])
Edit: Here are some useful links that have helped me on my path to enlightenment. Link juice for authors!