问题描述
我稍微修改并扩展了构建嵌套表单的示例,以实现第二级嵌套。一切都完美地显示在表格上。人的数据正确显示在两个嵌套级别。相应的 JS 脚本用于添加和删除嵌套表单。所有 3 个都是使用支架生成的。
但是当我点击更新时,只有主窗体和第一个嵌套级别(地址)被更新。第二级嵌套(嵌套地址)不会更新。虽然我也从控制器中的第二个嵌套级别获取参数("name"=>"UPDATE NAME OF NESTED ADDRESS")。
{
"_method"=>"patch","authenticity_token"=>"VZ09CR-aO2D4Wv3AwEa5PHXo-mA_--c6QPUN6f0Gb_9SJJSL2gIwzCl4G4SbzRy2t3wxJHytBWiPwysNJMrWgg","person"=>{
"first_name"=>"Liz","last_name"=>"Smith","addresses_attributes"=>{
"0"=>{
"_destroy"=>"false","kind"=>"Some kind","street"=>"Some street","nested_addresses_attributes"=>{
"0"=>{
"_destroy"=>"false","name"=>"UPDATE NAME OF NESTED ADDRESS","id"=>"1"
}
},"id"=>"10"}}},"commit"=>"Update Person","controller"=>"people","action"=>"update","id"=>"3"}
我知道即使是第一个嵌套级别也在幕后神奇地处理,但我不明白如何?以及如何处理第二级?通常,创建更新、删除方法不适用于第二级嵌套。
模型
class Person < ApplicationRecord
has_many :addresses,inverse_of: :person,:dependent => :destroy
has_many :nested_addresses,through: :addresses,:dependent => :destroy
accepts_nested_attributes_for :addresses,allow_destroy: true,reject_if: :all_blank
accepts_nested_attributes_for :nested_addresses,reject_if: :all_blank
validates :first_name,presence: true
validates :last_name,presence: true
end
class NestedAddress < ApplicationRecord
belongs_to :address
validates :name,presence: true
end
class Address < ApplicationRecord
belongs_to :person,optional: true
has_many :nested_addresses,inverse_of: :address,:dependent => :destroy
accepts_nested_attributes_for :nested_addresses,reject_if: :all_blank
validates :kind,presence: true
validates :street,presence: true
end
控制器
def person_params
params.require(:person).permit(:first_name,:last_name,addresses_attributes: [:id,:kind,:street,:_destroy],nested_addresses_attributes: [:id,:name,:_destroy])
end
def address_params
params.require(:address).permit(:kind,:person_id,:_destroy])
end
def nested_address_params
params.require(:nested_address).permit(:name,:address_id)
end
people/_form.html.erb
<%= form_with model: @person,local: true do |f| %>
<%= render "shared/validation-messages",object: @person %>
<%= f.label :first_name %>
<%= f.text_field :first_name,class: 'form-control' %>
<%= f.label :last_name %>
<%= f.text_field :last_name,class: 'form-control' %>
<br>
<fieldset>
<legend>Addresses:</legend>
<%= f.fields_for :addresses do |addresses_form| %>
<%= render "address_fields",f: addresses_form %>
<% end %>
<br>
<%= link_to_add_fields "Add Addresses",f,:addresses,'btn btn-outline-secondary'%>
</fieldset>
<br>
<%= f.submit class: 'btn btn-success' %>
<% if params[:action] === "edit" && params[:controller] === "people" %>
<%= link_to "Delete Person",person_path(@person),method: :delete,data: { confirm: "Are You Sure?" },class: 'btn btn-outline-danger' %>
<% end %>
<% end %>
people/_address_fields.html.erb
<div class="card nested-fields">
<div class="card-header">
<div><%= f.object.id %></div>
</div>
<div class="card-body">
<%= f.hidden_field :_destroy %>
<div>
<%= f.label :kind %>
<%= f.text_field :kind,class: 'form-control' %>
</div>
<div>
<%= f.label :street %>
<%= f.text_field :street,class: 'form-control' %>
</div>
<br>
<fieldset>
<legend>Nested addresses:</legend>
<%= f.fields_for :nested_addresses do |nested_addresses_form| %>
<%= render "nested_address_fields",f: nested_addresses_form %>
<% end %>
<br>
<%= link_to_add_fields "Add Nested Addresses",:nested_addresses,'btn btn-outline-secondary btn-sm' %>
</fieldset>
<br>
<div>
<%= link_to "Remove address",'#',class: "remove_fields btn btn-outline-danger btn-sm" %>
</div>
</div>
</div>
people/_nested_address_fields.html.erb
<div class="card nested-fields">
<div class="card-body">
<%= f.hidden_field :_destroy %>
<div>
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<br>
<div>
<%= link_to "Remove nested address",class: "remove_fields btn btn-outline-danger btn-sm" %>
</div>
</div>
<br>
</div>
helpers/application_helper.rb
def link_to_add_fields(name,association,cl)
new_object = f.object.send(association).klass.new
id = new_object.object_id
fields = f.fields_for(association,new_object,child_index: id) do |builder|
render(association.to_s.singularize + "_fields",f: builder)
end
link_to(name,class: 'add_fields ' + cl,data: {id: id,fields: fields.gsub("\n","")},role: 'button')
end
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)