Ruby on Rails fields_for表单助手问题

时间:2009-08-06 00:30:07

标签: ruby-on-rails xhtml

我正在使用带有循环的field_for表单助手:

<% f.fields_for :permissions do |permission_form| %>
    <tr>
      <td><%= permission_form.object.security_module.name %><%= permission_form.hidden_field(:security_module_id) %></td>
      <td><%= permission_form.object.security_module.description %></td>
    <tr>
<% end %>

以上代码的结果输出为:

    <input id="role_permissions_attributes_0_id" name="role[permissions_attributes][0][id]" type="hidden" value="76" />
    <tr>
      <td>Diary<input id="role_permissions_attributes_0_security_module_id" name="role[permissions_attributes][0][security_module_id]" type="hidden" value="13" /></td>
       <td>Access to the Diary Module</td>
    </tr>
    <!-- next input field then <tr> tag -->

此标记的问题在于输入标记落在tr标记之外,因此导致XHTML的验证问题。

有谁知道我如何让输入标签落入tr标签内,从而为我提供有效的XHTML 1.0 STRICT标记?

由于

3 个答案:

答案 0 :(得分:4)

如果你看看Rails源代码,你会发现它。

# in actionpack/lib/action_view/helpers/form_helper.rb
def fields_for_nested_model(name, object, args, block)
  if object.new_record?
    @template.fields_for(name, object, *args, &block)
  else
    @template.fields_for(name, object, *args) do |builder|
      @template.concat builder.hidden_field(:id)
      block.call(builder)
    end
  end
end

请注意,它正在此处直接添加隐藏字段,并且看起来没有任何选项可以更改此行为。最简单的事情可能是创建自己的自定义表单构建器。

# in lib/no_id_form_builder.rb
class NoIdFormBuilder < ActionView::Helpers::FormBuilder
  private
  def fields_for_nested_model(name, object, args, block)
    @template.fields_for(name, object, *args, &block)
  end
end

然后在表单中使用它。您需要手动添加id字段。

<% f.fields_for :permissions, :builder => NoIdFormBuilder do |permission_form| %>
  <tr>
    <td>
      <%= permission_form.object.security_module.name %>
      <%= permission_form.hidden_field(:security_module_id) %>
      <%= permission_form.hidden_field(:id) unless permission_form.object.new_record? %>
    </td>
    <td><%= permission_form.object.security_module.description %></td>
  <tr>
<% end %>

您可能想要提交灯塔票。也许:skip_id_field fields_for选项可以执行此操作。

答案 1 :(得分:2)

从2.3.5开始,有一种解决方法。如果您明确放置:id字段,则不会为您隐式添加它:

<% form_for @foo do |f| %> 
<table> 
  <tbody> 
    <% f.fields_for :bars do |bf| %> 
      <tr>
        <td>
          <%= bf.hidden_field :id %>
          <%= bf.text_field :name %>
        </td> 
      </tr> 
    <% end %> 
  </tbody> 
</table> 
<% end %>

请参阅 https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/3259

答案 2 :(得分:0)

轻微纠正:

:builder选项需要包含fields_for,而不是fields_for。