【问题标题】:RoR - helper method that calls fields_for a variable number of timesRoR - 调用 fields_for 可变次数的辅助方法
【发布时间】:2013-03-30 21:10:47
【问题描述】:

在我的 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 %>

知道我该如何做到这一点吗?

【问题讨论】:

    标签: ruby-on-rails fields-for


    【解决方案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
    

    【讨论】:

      【解决方案2】:
      <%= 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 %>
      

      【讨论】:

      • 我意识到这可以完成工作,但是对于我的情况需要太多的输入,我可能会在两个属性集中嵌套一些东西,并且只为单个输入打开该嵌套,然后必须做一些完全不同的事情。
      • 这是一种快速而肮脏的方法——对原型设计很有用,但它对列顺序的依赖性太大,无法在许多应用程序中使用。这是一种有趣的技术,就像你自己的方法一样。干杯
      猜你喜欢
      • 1970-01-01
      • 2014-11-19
      • 1970-01-01
      • 1970-01-01
      • 2018-06-21
      • 2011-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多