我正在尝试更新嵌套表单。客户端表已成功更新,但位置表未更新。而不是创建一个新的位置。你们有什么解决办法吗?我已经花了一天的时间。
我的模特:
class Client < ActiveRecord::Base
has_many :locations, :dependent => :destroy
accepts_nested_attributes_for :locations, :allow_destroy => true, :update_only => true
end
class Location < ActiveRecord::Base
belongs_to :client
end
Selectcom::Application.routes.draw do
resources :clients
end
我的控制器:
class ClientsController < ApplicationController
before_action :set_client, only: [:edit, :update]
def index
@clients = Client.paginate(page: params[:page])
end
def new
@client = Client.new
end
def create
@client = Client.new(client_params)
if @client.save
flash[:success] = "Client added successfully"
redirect_to clients_path
else
render 'new'
end
end
def edit
end
def update
if @client.update(only_client_params)
flash[:success] = "Job updated successfully"
redirect_to clients_path
else
render 'edit'
end
end
private
def set_client
@client = Client.find(params[:id])
end
def client_params
params.require(:client).permit(
:name,
:phone,
:fax,
:url,
:address,
:city,
locations_attributes: [
:site,
:fax,
:phone,
:url,
:address,
:_destroy
]
)
end
end
这是客户的edit.html.erb表单
<%= form_for(@client, class: 'form-horizontal') do |f| %>
<%= render(partial: 'client_field', locals: {f: f}) %>
<%= f.fields_for :locations do |l| %>
<%= l.hidden_field :client_id, value: @client.id %>
<%= l.hidden_field :_destroy %>
<%= l.text_field :site, class: 'form-control' %>
<% end %>
<%= f.submit "Save", class: "btn lg-button" %>
<% end %>
实际上,您在这里有两个问题。模型中的一个参数和控制器中允许的参数。让我们深入研究它们:
1)型号
与集合关联一起使用时,此update_only
选项将被忽略(这是您的情况),如Rails文档中所述:
对于一对一关联,此选项允许您指定在关联记录已存在时如何使用嵌套属性。通常,可以使用新的属性值集更新现有记录,也可以用包含这些值的全新记录来替换现有记录。
默认情况下,:update_only选项为false,并且嵌套属性仅在包含记录的:id值时才用于更新现有记录。否则,将实例化一条新记录并用于替换现有记录。
但是,如果:update_only选项为true,则无论是否存在:id,嵌套属性都将始终用于更新记录的属性。对于集合关联,该选项将被忽略。
因此,第一步将是删除Client类的update_only
选项,因为您与位置具有关联(集合关联),因此它将被忽略:has_many
class Client < ActiveRecord::Base
has_many :locations, :dependent => :destroy
accepts_nested_attributes_for :locations, :allow_destroy => true
end
2)控制器
您必须允许:id
该:locations_attributes
阵列的密钥。由于update_only
忽略了模型中的选项,因此Rails需要参数来表明它是存在的记录,并且正在更新而不是创建记录。
您可以在client_params方法中使用以下命令解决您的问题(注意在id
密钥中添加了:locations_attributes
密钥):
def client_params
params.require(:client).permit(
:name,
:phone,
:fax,
:url,
:address,
:city,
locations_attributes: [
:id, # Should be present; otherwise, Rails thinks that is a new record
:site,
:fax,
:phone,
:url,
:address,
:_destroy
]
)
end
希望对您有所帮助!
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句