向FormBuilder添加一个方法,该方法调用呈现部分的辅助方法

所以我有这个辅助方法,对吧?

def table_form_field(name_or_options = nil, *args, &block) # ... render :partial => "snippets/table_form_field", :locals => options end 

这很好,除非有时我想将它与表单构建器一起使用,为此,我必须这样称呼它:

 table_form_field(:foo, :form_builder => f) do |name| f.text_field name end 

必须手动指定:form_builder是很烦人的。 所以我的目标是扩展ActionView::Helpers::FormBuilder并为其添加一个新方法,如下所示:

 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 

您可以从表单构建器中访问名为@template的实例变量,这样您就可以在@template变量上调用table_form_field

例如,我将创建一个inheritance自ActionView :: Helpers :: FormBuilder的自定义表单构建器

 class MyFormBuilder < ActionView::Helpers::FormBuilder def table_form_field(*attrs, &block) @template.table_form_field(*attrs, &block) end end 

然后在您的form_for中,您可以告诉它使用您的自定义表单构建器

 <%= form_for @myobject, :builder => MyFormBuilder do |f| %> <%= f.table_form_field :myfield do %> <% end %> <%= end %>