Rails 4-强参数-嵌套对象


144

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

因此,这是我发送到服务器的JSON字符串:

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

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

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

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

如果我刚设置:

params.require(:measurement).permit!

一切都按预期方式保存,但这当然会破坏强大参数所提供的安全性。

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



1
@vinodadhikary是正确的……我认为操作指导感到困惑。当您想允许嵌套属性时,您确实在数组中指定了嵌套对象的属性。在另一方面,如果你想嵌套多个对象,那么你把它包装散里面......看到api.rubyonrails.org/classes/ActionController/...github.com/rails/rails/blob/master/actionpack/lib/...
j03w

@ j03w,感谢您链接到源。现在很清楚。您应该在此添加一个答案,因为我认为这会帮助很多其他人。
2013年

Answers:


181

当您想允许嵌套属性时,您确实在数组中指定了嵌套对象的属性。在你的情况下

按照@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

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


5
两种情况在此答案中都是相同的,实际上,只是大括号在{:groundtruth => [...]}周围是可选的;这是一个散列,但解释器能够确定散列的开始和结束位置,而无需使用大括号。
口语代码

嵌套的属性数组不允许嵌套的属性。嵌套的属性和attr_accessor在我的应用程序中列为“不允许的参数”。仍在寻找安全的解决方案。
Katarzyna

如果有多个嵌套对象,则还应允许其ID起作用。这里更多的信息:stackoverflow.com/questions/18308714/...
法布里斯Carrega

1
这仅允许一组嵌套属性。在一对多的情况下,这将不起作用。
AKWF,

23

我发现此建议对我的情况有用:

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

检查Xavier在github上的评论的链接

这种方法将整个params [:measurement] [:groundtruth]对象列入白名单。

使用原始问题属性:

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

4
请注意,这仍然会在日志中显示为不允许的参数,但是无论如何,模型都会接受它们。
Weston Ganger

5
不确定Rails 4,但是在我的Rails 5项目中,我必须打电话permit!将其列入白名单,否则在点击它后仍然不允许。在这种情况下,将是params[:measurement][:groundtruth].permit!
nayiaw

@nayiaw我也收到不允许的消息,但是添加permit!会增加此错误NoMethodError (undefined method 许可!for#<Array:0x007f80cb71ea00>):`
wuliwong

@wuliwong permit!方法在中不可用Array。您需要访问相应的类实例才能访问permit!(已经有一段时间了,所以我忘记了类名,但这有点像ActionController::Parameters基于此页面)。
nayiaw

8

允许嵌套对象:

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

0

如果是Rails 5,则由于新的哈希符号: params.permit(:name, groundtruth: [:type, coordinates:[]])可以正常工作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.