Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cleanly update a list of HABTM associations in Rails 4?

I'm trying to update a User record with the list of associated Addresses, connected through the has and belongs to many association.

The request body I'm sending through javascript is:

{"id":10,"name":"John Smith", "address_ids":[4,8]}

This is what I'm getting in the Rails server log:

Started PUT "/api/users/10" for 127.0.0.1 at 2013-10-03 16:30:43 +0200

Processing by Api::UsersController#update as HTML

Parameters: {"id"=>"10", "name"=>"John Smith", "address_ids"=>[4, 8], "user"=>{"id"=>"10", "name"=>"John Smith"}}

The thing to notice above is the address_ids array is not making it into the user hash according to the log.

In the controller i'm using strong parameters and updating the User like so:

attributes = params.require(:user).permit(:id, :name, {:address_ids => []}) 
@user.update_attributes(attributes)

The problem is the attributes don't contain the address_ids at the point of update so the associated records are not getting updated.

Temporary Solution

I've worked around the issue manually assigning the address_ids key to the attributes after they come back from the strong parameters check like so:

attributes = params.require(:user).permit(:id, :name, {:address_ids => []})
if params.has_key?(:address_ids)   
  attributes[:address_ids] = params[:address_ids] 
end
@user.update_attributes(attributes)

This works fine but doesn't seem to me this is how it is supposed to work? Why are the adderss_ids not getting auto assigned? How can this be implemented in a clear way?

like image 591
mrt Avatar asked Oct 03 '13 15:10

mrt


1 Answers

If you want the addresses saved with the User you need to ensure your client side code sends the address_ids parameters as follows:

Parameters: {"user"=>{"id"=>"10", "name"=>"John Smith", "address_ids"=>["4", "8"]}}

The input field name attribute will be something like:

<input name="user[address_ids][]">

I also noticed you seem to have your user attributes repeated in your parameters so you may want to carefully review how your client code is generating the request.

like image 130
Andrew Hacking Avatar answered Sep 19 '22 15:09

Andrew Hacking