Rails-强参数-嵌套对象

我有一个很简单的问题,但是到目前为止还没有找到解决的办法。

下面是我发送给服务器的 JSON 字符串:

{
"name" : "abc",
"groundtruth" : {
"type" : "Point",
"coordinates" : [ 2.4, 6 ]
}
}

使用新的许可证方法,我得到了:

params.require(:measurement).permit(:name, :groundtruth)

这不会抛出任何错误,但是创建的数据库条目包含 null而不是 ground truth 值。

如果我设置:

params.require(:measurement).permit!

所有内容都按照预期保存,但是当然,这会扼杀强参数提供的安全性。

我已经找到了解决方案,如何允许数组,但没有一个使用嵌套对象的例子。这必须是可能的,因为它应该是一个非常常见的用例。那么,它是如何工作的?

122938 次浏览

当您想要允许嵌套属性时,您确实需要指定数组中嵌套对象的属性,这听起来很奇怪。对你来说是的

更新由@RafaelOliveira 建议

params.require(:measurement)
.permit(:name, :groundtruth => [:type, :coordinates => []])

另一方面,如果你想嵌套多个对象,然后你把它包装在一个散列... 像这样

params.require(:foo).permit(:bar, {:baz => [:x, :y]})


Rails 实际上有很好的关于这方面的文档: http://api.rubyonrails.org/classes/ActionController/Parameters.html#method-i-permit

为了进一步澄清,您可以查看 permitstrong_parameters本身的实现: https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/strong_parameters.rb#L246-L247

我发现这个建议对我很有用:

  def product_params
params.require(:product).permit(:name).tap do |whitelisted|
whitelisted[:data] = params[:product][:data]
end
end

查查 Xavier 在 github 上的评论。

这种方法将整个 params [ : 测量][ : ground truth ]对象列为白名单。

使用原始问题属性:

  def product_params
params.require(:measurement).permit(:name, :groundtruth).tap do |whitelisted|
whitelisted[:groundtruth] = params[:measurement][:groundtruth]
end
end

允许嵌套对象:

params.permit( {:school => [:id , :name]},
{:student => [:id,
:name,
:address,
:city]},
{:records => [:marks, :subject]})

如果是 Rails 5,由于新的散列表示法: params.permit(:name, groundtruth: [:type, coordinates:[]])可以正常工作。