如何在Rails 4中干净地更新HABTM关联列表?

mrt*_*mrt 8 ruby-on-rails has-and-belongs-to-many strong-parameters ruby-on-rails-4

我正在尝试User使用关联列表更新记录Addresses,通过has连接并属于许多关联.

我通过javascript发送的请求正文是:

{"id":10,"name":"John Smith", "address_ids":[4,8]}
Run Code Online (Sandbox Code Playgroud)

这是我在Rails 服务器日志中得到的:

在2013-10-03 16:30:43 +0200开始PUT"/ api/users/10"为127.0.0.1

由Api :: UsersController处理#update为HTML

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

上面要注意的是address_ids数组没有user根据日志将其变为哈希.

控制器中我使用强参数并更新User如下:

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

问题是属性在更新时不包含address_ids,因此关联的记录不会更新.

临时解决方案

我已经解决了这个问题,手动将address_ids密钥分配给attributes他们从强参数检查后回来,如下所示:

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)
Run Code Online (Sandbox Code Playgroud)

这工作正常,但在我看来这不是它应该如何工作?为什么adderss_ids没有自动分配?如何以明确的方式实施?

And*_*ing 9

如果您需要用户保存的地址,您需要确保客户端代码发送address_ids如下参数:

Parameters: {"user"=>{"id"=>"10", "name"=>"John Smith", "address_ids"=>["4", "8"]}}
Run Code Online (Sandbox Code Playgroud)

输入字段name属性将类似于:

<input name="user[address_ids][]">
Run Code Online (Sandbox Code Playgroud)

我还注意到您的参数中似乎重复了您的用户属性,因此您可能需要仔细检查客户端代码生成请求的方式.