Actually, you have two issues here. One in your Model and other in your Controller permitted params. Let's dig into them:
1) Model
The update_only
option is ignored when used with collection association (it is your case), as said in Rails documentation:
For a one-to-one association, this option allows you to specify how nested attributes are to be used when an associated record already exists. In general, an existing record may either be updated with the new set of attribute values or be replaced by a wholly new record containing those values.
By default the :update_only option is false and the nested attributes are used to update the existing record only if they include the record's :id value. Otherwise a new record will be instantiated and used to replace the existing one.
However if the :update_only option is true, the nested attributes are used to update the record's attributes always, regardless of whether the :id is present. The option is ignored for collection associations.
So, the first step would be removing the update_only
option of your Client class, because it will be ignored since you have a has_many
association (collection association) with locations:
class Client < ActiveRecord::Base
has_many :locations, :dependent => :destroy
accepts_nested_attributes_for :locations, :allow_destroy => true
end
2) Controller
You have to permit the :id
key for the :locations_attributes
array. Since your update_only
option in the model was ignored, Rails needs the param to tell that it is a record that exists and it's being updated rather than created.
You can solve your issue using the following in your client_params method (note the addition of the id
key in your :locations_attributes
key):
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
I hope it helps !!