问题
So I've got this helper method, right?
def table_form_field(name_or_options = nil, *args, &block)
# ...
render :partial => "snippets/table_form_field", :locals => options
end
It's nice, except sometimes I want to use it with a form builder, and to do that I'd have to call it like this:
table_form_field(:foo, :form_builder => f) do |name|
f.text_field name
end
It's annoying to have to specify :form_builder manually. So my goal is to extend ActionView::Helpers::FormBuilder
and add a new method to it, like so:
class ActionView::Helpers::FormBuilder
def table_form_field(name_or_options, options, &block)
if name_or_options.is_a?(Hash)
name_or_options[:form_builder] = self
else
options[:form_builder] = self
end
# But... how can I call the helper?
# Hmm, I'll try this:
klass = Class.new do
include ApplicationHelper
end
klass.new.send(:table_form_field, name_or_options, options, &block)
# Thank you, Mario, but your princess is in another castle!
#
# Basically, this tries to call render, and for obvious
# reasons, klass doesn't know how to render.
#
# So... what do I do?
end
end
回答1:
You can access an instance variable called @template
from within form builders so you can just call table_form_field
on the @template
variable.
For example, I would create a custom form builder that inherits from ActionView::Helpers::FormBuilder
class MyFormBuilder < ActionView::Helpers::FormBuilder
def table_form_field(*attrs, &block)
@template.table_form_field(*attrs, &block)
end
end
Then in your form_for you can tell it to use your custom form builder
<%= form_for @myobject, :builder => MyFormBuilder do |f| %>
<%= f.table_form_field :myfield do %>
<% end %>
<%= end %>
来源:https://stackoverflow.com/questions/7238798/adding-a-method-to-formbuilder-that-calls-a-helper-method-that-renders-a-partial