在 Rails 中使用数据表时,使用 "accepts_nested_attributes_for" 的 ID 字段消失
Id field using "accepts_nested_attributes_for" disappears when using datatables in Rails
背景:我正在使用 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", "age"=> 22, "_destroy"=> false}}....>
注意:我允许嵌套关联的参数中的所有属性,因此这不是关于参数允许的问题。
好的,我找到问题了。问题是使用 simple_fields_for(simple_form gem)在 tbody 和 tr 之间插入包含 id 的隐藏输入字段。
Datatables 删除任何此类输入 html 元素,因为它根据 https://validator.w3.org/ 无效 HTML 或因为它是隐藏的。
解决方案是在 td 中手动为 id 放置一个隐藏字段,然后数据表不会将其删除,因此您可以取回 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", "age"=> 22, "_destroy"=> false}}....>
注意:我允许嵌套关联的参数中的所有属性,因此这不是关于参数允许的问题。
好的,我找到问题了。问题是使用 simple_fields_for(simple_form gem)在 tbody 和 tr 之间插入包含 id 的隐藏输入字段。
Datatables 删除任何此类输入 html 元素,因为它根据 https://validator.w3.org/ 无效 HTML 或因为它是隐藏的。
解决方案是在 td 中手动为 id 放置一个隐藏字段,然后数据表不会将其删除,因此您可以取回 id 字段。