【问题标题】:how to correctly extend form_for / ActionView::Helpers::FormBuilder?如何正确扩展 form_for / ActionView::Helpers::FormBuilder?
【发布时间】:2011-06-08 09:03:36
【问题描述】:

这类似于Trying to extend ActionView::Helpers::FormBuilder,但我不想使用 :builder => MyThing。

我想扩展表单生成器以添加自定义方法。这是目前的情况:

module ActsAsTreeHelpers
  def acts_as_tree_block(method, &block)
    yield if block_given?
  end

end


ActionView::Helpers::FormBuilder.send :include, ::ActsAsTreeHelpers

控制台:

ruby-1.9.2-p180 :004 > ActionView::Helpers::FormBuilder.included_modules
=> [ActsAsTreeHelpers, ...]

但以下给了我:undefined method acts_as_tree_block for #<ActionView::Helpers::FormBuilder:0xae114dc>

<%= form_for thing do |form| %>
  <%= form.acts_as_tree_block :parent_id, {"test"} %>
<% end %>

我在这里缺少什么?

【问题讨论】:

    标签: ruby-on-rails-3 actionview formbuilder


    【解决方案1】:

    我也遇到了同样的问题。 我尝试在我的项目的 config/initializers 文件夹中添加一个名为 form_builder.rb 的新文件,它现在运行良好。

    以下是我的解决方案的一些内容。 base_helper.rb

    def field_container(model, method, options = {}, &block)
      css_classes = options[:class].to_a
      if error_message_on(model, method).present?
        css_classes << 'withError'
      end
      content_tag('p', capture(&block), :class => css_classes.join(' '), :id => "#{model}_#{method}_field")
    end
    

    form_builder.rb

    class ActionView::Helpers::FormBuilder
      def field_container(method, options = {}, &block)
        @template.field_container(@object_name,method,options,&block)
      end
    
      def error_message_on(method, options = {})
        @template.error_message_on(@object_name, method, objectify_options(options))
      end
    end
    ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| "<span class=\"field_with_errors\">#{html_tag}</span>".html_safe }
    

    _form.html.erb

    <%= f.field_container :name do %>
      <%= f.label :name, t("name") %> <span class="required">*</span><br />
      <%= f.text_field :name %>
      <%= f.error_message_on :name %>
    <% end %>
    

    【讨论】:

      【解决方案2】:

      接受的答案不再对我有用(Rails 5+)

      这是我为使其正常工作所做的更改(Rails 5.2.3):

      # config/initializers/custom_form_builder.rb
      class ActionView::Helpers::FormBuilder
        def my_custom_text_field_with_only_letters(method, options = {})
          options[:pattern] = "^[A-Za-z]+$"
          options[:title] = "Only letters please"
          text_field(method, options)
        end
      
        field_helpers << :my_custom_text_field_with_only_letters
      end
      

      field_helpers &lt;&lt; :my_custom_text_field_with_only_letters 确保您的新方法在您的所有申请表中都可用。

      根据doc,另一种可能性是扩展 FormBuilder ,添加您的自定义方法,然后在您想要的每个表单中指定要使用的 FormBuilder :

      class MyFormBuilder < ActionView::Helpers::FormBuilder
       def div_radio_button(method, tag_value, options = {})
      ...
      
      <%= form_for @person, :builder => MyFormBuilder do |f| %>
      <%= f.div_radio_button(:admin, "child") %>
      

      【讨论】:

        猜你喜欢
        • 2011-01-29
        • 2011-11-08
        • 2012-05-21
        • 2020-08-14
        • 1970-01-01
        • 2011-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多