Rails 4 - 强参数 - 嵌套对象

Ben*_*n M 135 ruby-on-rails nested-attributes strong-parameters ruby-on-rails-4

我有一个非常简单的问题.但到目前为止还没有找到解决方案.

所以这是我发送给服务器的JSON字符串:

{
  "name" : "abc",
  "groundtruth" : {
    "type" : "Point",
    "coordinates" : [ 2.4, 6 ]
  }
}
Run Code Online (Sandbox Code Playgroud)

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

params.require(:measurement).permit(:name, :groundtruth)
Run Code Online (Sandbox Code Playgroud)

这不会引发任何错误,但创建的数据库条目包含null而不是groundtruth值.

如果我只是设置:

params.require(:measurement).permit!
Run Code Online (Sandbox Code Playgroud)

所有东西都按预期保存,但当然,这会破坏强参数提供的安全性.

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

j03*_*03w 174

当您想要允许嵌套属性时听起来很奇怪,您可以在数组中指定嵌套对象的属性.在你的情况下,它会

按照@RafaelOliveira的建议更新

params.require(:measurement)
      .permit(:name, :groundtruth => [:type, :coordinates => []])
Run Code Online (Sandbox Code Playgroud)

另一方面,如果你想要嵌套多个对象,那么你将它包装在一个哈希中...就像这样

params.require(:foo).permit(:bar, {:baz => [:x, :y]})
Run Code Online (Sandbox Code Playgroud)


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

  • 两个案例在这个答案中是相同的,实际上,只是大括号在{:groundtruth => [...]}周围是可选的; 它是一个哈希,但是解释器能够确定哈希开始和结束的位置而没有明确的大括号. (5认同)

M.E*_*aka 22

我发现这个建议在我的案例中很有用:

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

查看Xavier对github的评论链接.

这种方法将整个参数[:measurement] [:groundtruth]对象列入白名单.

使用原始问题属性:

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

  • 不确定Rails 4但是在我的Rails 5项目中我必须将`permit!`称为白名单,否则在点击它之后它仍然是不允许的.在这种情况下,它将是`params [:measurement] [:groundtruth] .permit!` (5认同)
  • 只是旁注,这仍然会在日志中显示为未允许的参数,但模型仍会接受它们. (4认同)

Cod*_*iee 7

允许嵌套对象:

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