不在fields_for方法中调用自定义表单构建器

时间:2012-02-02 04:23:16

标签: ruby-on-rails

我有一个包含3个相关模型的嵌套表单。我希望我的自定义表单构建器PanelFormBuilder构建所有字段。但是,只有form_for似乎由我的表单构建器处理而fields_for没有 - 它会被默认处理。我不能为我的生活找出原因。

这有效:

<%= panel_form_for @firm do |f| %>

这不是:

<%= panel_fields_for @firm.company do |c| %>

以下是自定义方法:

module ApplicationHelper
  def panel_form_for(object, options = {}, &block)
    options[:builder] = PanelFormBuilder
    form_for(object, options, &block)
  end

  def panel_fields_for(object, options = {}, &block)
    options[:builder] = PanelFormBuilder
    fields_for(object, options, &block)
  end
end

这是自定义表单构建器

class PanelFormBuilder < ActionView::Helpers::FormBuilder
  delegate :content_tag, :tag, to: :@template

  %w[text_field text_area password_field].each do |method_name|
    define_method(method_name) do |name, *args|
      options = args.extract_options!
      options.merge!(:class => "required")
      super(name, *(args + [options]))
    end
  end
end

谁能告诉我我做错了什么?

由于

2 个答案:

答案 0 :(得分:1)

找到我自己的答案。事实证明我应该这样做:

<%= panel_form_for @firm do |f| %>

其次是:

<%= f.fields_for :company do |c| %>

我根本不需要panel_fields_for

答案 1 :(得分:1)

查看fields_for

的定义
fields_for(record_name, record_object = nil, options = {}, &block)

当您使用块作为参数调用fields_for时,Ruby将无法确定您指定的options参数实际上是选项,而是认为它是{{1参数。

您只需将record_object作为第二个参数传递,您的自定义构建器就会被实例化:

nil

在您无法访问表单的构建器对象的情况下,例如,当您从单独的fields_for(object, nil, options, &block) 块创建某些字段时,这可能很有用。