1

我的项目中有一个自定义表单构建器,在初始化程序中使用以下代码:

class CustomFormBuilder < ActionView::Helpers::FormBuilder

  def submit(label, *args)
    options = args.extract_options!
    new_class = options[:class] || "btn"
    super(label, *(args << options.merge(:class => new_class)))
  end

  def text_field(label, *args)
    options = args.extract_options!
    new_class = options[:class] || "textbox"
    super(label, *(args << options.merge(:class => new_class)))
  end

end

# Set CustomBuilder as default FormBuilder
ActionView::Base.default_form_builder = CustomFormBuilder

提交定义工作并将类 btn 附加到提交输入,但是text_field定义似乎不起作用,因为类文本框没有附加到文本输入。

查看 FormBuilder 的文档后,我注意到submit被列为方法,而text_field没有。我需要弄清楚的是如何正确覆盖使用form_for生成表单时使用的text_field方法。如果它有助于我使用 Ruby 2.0.0 和 Rails 3.2.13。我还查看了一个示例here,它显示了自定义 FormBuilder 类中的text_field方法,所以我想知道在 Rails 3 中,这个方法是否已从FormBuilder中删除并放在其他地方。任何有关如何实现这一目标的见解将不胜感激。

以下是我的解决方案 (基于 PinnyM 提供的信息)

class CustomFormBuilder < ActionView::Helpers::FormBuilder

  def submit(label, *args)
    options = args.extract_options!
    options[:class] = "btn" if !options[:class].present?
    super(label, *(args << options))
  end

  def self.create_tagged_field(method_name)
    case method_name
    when 'text_field'
      define_method(method_name) do |name, *args|
        options = args.extract_options!
        options[:class] = "textbox" if !options[:class].present?
        super(name, *(args << options))
      end
    end
  end

  field_helpers.each do |name|
    create_tagged_field(name)
  end

end
4

1 回答 1

0

FormBuilder使用元代码为大多数表单标签(包括text_field)生成方法。FormHelper它为此目的借用了实例方法,排除了需要不同实现的特定标签,并循环通过剩余的标签为它们自动生成方法。生成的相关代码如下所示:

(field_helpers - %w(label check_box radio_button fields_for hidden_field file_field)).each do |selector|
  class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
    def #{selector}(method, options = {}) # def text_field(method, options = {})
      @template.send( # @template.send(   
        #{selector.inspect}, # "text_field",
        @object_name, # @object_name,
        method, # method,
        objectify_options(options)) # objectify_options(options))
    end # end
    RUBY_EVAL
end
于 2013-04-22T15:17:42.240 回答