Search code examples
jqueryruby-on-railsdatatablessimple-formaccepts-nested-attributes

Id field using "accepts_nested_attributes_for" disappears when using datatables in Rails


Background: I am using simple_form to render nested attributes of an association in rails. I have applied jquery-datatables gem on the edit form for the nested association using simple_fields_for.

My model is:

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

My view is:

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}?"}

controller

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,
  });

Problem: With the above, the id field in the nested association disappears from the params. Without datatables applied it reappears. This causes rails to create new fields rather than updating the existing ones with datatables enabled.

params without datatables

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

params with datatables (no id field present)

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

Note: I am allowing all the attributes in the params for the nested association, so its not an issue about params permit.


Solution

  • Alrighty, I found the problem. The issue was that using simple_fields_for (of simple_form gem) inserts the hidden input field containing the id in between the tbody and the tr.

    Datatables remove any such input html element either because it is invalid HTML as per https://validator.w3.org/ or because it is hidden.

    Solution was to place a hidden field for id manually in the td and then datatables does not take that out and hence you get the id field back.