在我的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 %>
你知道我该怎么做吗?
我实现了以下帮助方法(可能不是最好的方法)。
视图中的函数调用示例:
<%= 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
<%= 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 %>