在Rails中使用数据表时,使用“ accepts_nested_attributes_for”的ID字段消失

问题描述

背景:我正在使用simple_form在Rails中呈现关联的嵌套属性。我已经使用simple_fields_for在嵌套关联的编辑表单上应用了jquery-datatables gem。

我的模特是:

has_many :foos,dependent: :destroy
accepts_nested_attributes_for :foos,reject_if: :all_blank,allow_destroy: true

我的看法是:

edit.html.slim

     table.table.table-bordered#foo-requirements-table
            thead
              tr
                th Name
                th Age
               tbody.foo-row
              = form.simple_fields_for :foos do |f|
                = render("foo_fields",f: f)

_foo_fields.html.slim

tr class="#{foo_colour(f.object)} nested-fields"
  td
    = f.input :name,label: false,required: true
  td
    = f.select :age,Foo.foos.map {|p,_v| [p.upcase,p] },{},class: "form-control foo-colour"
  td
    = link_to_remove_association fa_icon("trash"),f,class: "btn btn-danger bottom-margin",data: {confirm: "Are you sure that you want to remove the row #{f.object&.age}?"}

控制器

def edit
    @bar= Bar.find_by(id: params[:id])
    build_foos if @bar.foos.empty?
end

def build_foos
    ["a","b","c"].each do |action|
      @bar.foos.build(name: action)
    end
end

JavaScript

 $("#foo-requirements-table").DataTable({
    paging: false,});

问题:通过以上操作,嵌套关联中的id字段从参数中消失了。如果没有应用数据表,它将重新出现。这会导致Rails创建新字段,而不是在启用了数据表的情况下更新现有字段。

没有数据表的参数

<ActionController::Parameters {"0"=>{"name"=>"a","age"=> 22,"_destroy"=> false,"id" => 12}}....>

具有数据表的参数(不存在id字段)

<ActionController::Parameters {"0"=>{"name"=>"a","_destroy"=> false}}....>

注意:我允许嵌套关联的params中的所有属性,因此这与params allow无关。

解决方法

好的,我发现了问题。问题在于,使用simple_form gem的simple_fields_for在tbody和tr之间插入包含id的隐藏输入字段。

数据表会删除所有此类输入html元素,原因是根据https://validator.w3.org/而言,该元素是无效的HTML,或者是已隐藏。

解决方案是在td中手动放置一个id的隐藏字段,然后数据表不会将其删除,因此您将id字段取回。