繁体   English   中英

Rails允许嵌套的哈希属性

[英]Rails permit nested hash attributes

控制器接收JSON对象

{
  user: {
    name: "string",
    details: {
      info1: "string",
      info2: []
    }
  }
}

在权限期间,控制器知道可以允许某些定义的字段(如名称)和带有所有嵌套属性的哈希字段详细信息(也包括数组) 对于这种情况正确的解决方案是什么?

糟糕的解决方案

  1. permit不能使用,因为我必须选择用户允许的字段

  2. tap do |whitelisted| 无法使用,因为它不会使该字段“允许”

  3. 用户不能使用下面的情况,因为使用数组不起作用

    details_keys = params[:user][:details].keys

    params.require(:user).permit(:name, details: details_keys)

添加空数组可能会起作用。 您可以关闭对嵌套属性的验证吗? 您是否正在创建不受控制的动态随机输入字段?

您要传递动态字段吗? 在这种情况下,以下方法可能会起作用

为动态键配置强参数

如果要允许具有允许的标量值数组的键,则只需将键映射到一个空数组即可:

params.permit(key: [])

允许的标量类型为String, Symbol, NilClass, Numeric, TrueClass, FalseClass, Date, Time, DateTime, StringIO, IO, ActionDispatch::Http::UploadedFile, and Rack::Test::UploadedFile

因此,当数组包含一些非标量值(例如哈希)时,则必须进一步允许在数组中使用嵌套键。

假设您具有以下结构:

{
  key: [
    {
      attr1: 'string',
      attr2: 10
    },
    {
      attr1: 'another string',
      attr2: 100
    }
  ]
}

那么许可将以这种方式进行:

params.permit(key: [:attr1, :attr2])

现在,假设您的情况如下:

{
  user: {
    name: "sting",
    details: {
      info1: "string",
      info2: [1, true, :sym] // assume it contains only permitted scalar values
    }
  }
}

许可将是:

params.require(:user).permit(:name, details: [:info1, info2: []])

为了实现这一点,假设details有5个具有允许标量值的属性,以及3个以上也只有标量值的数组属性。

首先选择details的5个非数组键:

non_array_keys = params[:user][:details].reject { |_, v| v.class == Array }.keys

接下来是内部的3个数组键details

array_keys = params[:user][:details].select { |_, v| v.class == Array }.keys.map { |k| { k => [] } }

现在可以通过以下方式准备details_keys

details_keys = non_array_keys << array_keys
details_keys.flatten!

最终许可将如下所示:

params.require(:user).permit(:name, details: details_keys)

如果嵌套数组将包含非标量值,那么我想您到此为止已经对如何适应您的更改有了足够的了解!

免责声明 :这种自动化是params.require(:user).permit! ,因为不是简单地调用params.require(:user).permit! ,而是执行所有这些params.require(:user).permit! 就足够了。 但这会将:user参数哈希及其任何子哈希标记为允许,并且不检查允许的标量,任何东西都可以接受。 使用permit!时应格外小心permit! ,因为它将允许批量分配所有当前和将来的模型属性。

有关详细信息,我强烈建议您仔细阅读有关强参数Rails官方指南

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM