RoR - 调用fields_for可变次数的辅助方法

时间:2013-03-30 21:10:48

标签: ruby-on-rails fields-for

在我的Rails应用中,我有一个多次使用fields_for的表单,有时会将调用嵌套到fields_for

不幸的是,图形设计师坚持认为输入字段的排序方式不能根据它们所属的模型进行分组。因此,我想制作一个可以轻松构建fields_for块的帮助器,但是我看不到如何使用辅助方法来嵌套可变数量的块。

为了说明,我设想代码如下所示:

<%= form_for @object do |f| %>
  <!-- The helper method should have a similar effect to the following... -->
  <%= f.fields_for :assoc_a do |assoc_a_builder| %>
    <%= assoc_a_builder.fields_for :assoc_b do |assoc_b_builder| %>
      <%= assoc_b_builder.text_field :field_name %>
    <% end %>
  <% end %>      
  <!-- ...when given the following data... -->
  <%= my_helper [f, :assoc_a, :assoc_b], :text_field, :field_name %>

<% end %>

知道我怎么能做到这一点吗?

2 个答案:

答案 0 :(得分:1)

我实现了以下帮助方法(可能不是最好的方法)。

视图中的函数调用示例:

<%= form_for @object do |builder| %>
  <%= nested_form_field 'My label text', [builder, :association_name, :field_name], :collection_select, :my_model_id, MyModel.all, :id, :name %>
<% end %>

功能定义:

  # Outputs a label and input, nesting calls to fields_for if 'form' arg is an Array.
  # e.g. <%= nested_form_field nil, [builder, :approved_details], :collection_select, :my_model_id, MyModel.all, :id, :name %>
  # Make label_text nil for just the input tag, no wrapping elements.
  def nested_form_field label_text, form, helper_method, field, *args_for_helper_method
    if form.is_a? Array
      if form.length > 1
        form.shift.fields_for form.first do |builder|
          form[0] = builder
          nested_form_field label_text, form, helper_method, field, *args_for_helper_method
        end
      else
        nested_form_field label_text, form.first, helper_method, field, *args_for_helper_method
      end
    else
      if label_text.nil?
        form.send helper_method, field, *args_for_helper_method
      else
        %Q(<div class=row>
        <div class=span4>#{label_text}</div>
        #{ form.send helper_method, field, *args_for_helper_method }
        </div>).html_safe
      end
    end
  end

答案 1 :(得分:0)

<%= simple_form_for(@primer3) do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <% @primer3.attributes.each_pair do |name, value| %>
      <%= f.input name if value %>
    <% end %>
  </div>

  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>