具有嵌套哈希的强参数

Strong parameters with nested hash

我有以下参数,无法使强参数起作用。

这是我的基本代码,为简单起见,可在 Rails 控制台中运行:

json = {
  id: 1,
  answers_attributes: {
    c1: { id: "", content: "Hi" },
    c2: { id: "", content: "Ho" }
  }
}

params = ActionController::Parameters.new(json)

我读过的所有内容都说以下应该有效,但它只给了我 idanswers_attributes:

的空散列
params.permit(:id, answers_attributes: [:id, :content])
=> { "id"=>1, "answers_attributes"=>{} }

如果我改为手动列出 c1c2(如下所示)它会起作用,但这真的很愚蠢,因为我不知道用户会提供多少答案,这是很多重复:

params.permit(:id, answers_attributes: { c1: [:id, :content], c2: [:id, :content] })
=> {"id"=>1, "answers_attributes"=>{"c1"=>{"id"=>"", "content"=>"Hi"}, "c2"=>{"id"=>"", "content"=>"Ho"}}}

我尝试用 01 替换 c1c2,但我仍然必须手动提供 01 在我的许可声明中。

如何允许未知长度的嵌套属性数组?

使用如下语法完成:

answers_attributes: [:id, :content]

问题是您在 answers_attributes 中使用的键。它们应该是 answers_attributes 的 ID,或者在新记录的情况下 0.

更改这些会得到您预期的结果:

json = {
  id: 1,
  answers_attributes: {
    "1": { id: "", content: "Hi" },
    "2": { id: "", content: "Ho" }
  }
}

params = ActionController::Parameters.new(json)

params.permit(:id, answers_attributes:[:id, :content])
=>  {"id"=>1, "answers_attributes"=>{"1"=>{"id"=>"", "content"=>"Hi"}, "2"=>{"id"=>"", "content"=>"Ho"}}}

编辑:看来 0 不是唯一的键,我的意思是如果您有两个 new 记录怎么办。我使用 nested_form,它似乎使用了一个很长的随机数。

您的 answers_attributes 包含不允许的 c1 和 c2。 http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

方法 1: 您可以将嵌套属性作为散列数组传递。

json = {
  id: 1,
  answers_attributes: [ { id: "", content: "Hi" }, { id: "", content: "Ho" } ]
}

现在params.permit(:id, answers_attributes: [:id, :content])给出

{"id"=>1, "answers_attributes"=>[{"id"=>"", "content"=>"Hi"}, {"id"=>"", "content"=>"Ho"}]}

方法 2: 您可以像

这样的散列散列传递
json = {
  id: 1,
  answers_attributes: {
    c1: { id: "", content: "Hi" },
    c2: { id: "", content: "Ho" }
  }
}

WAY 1WAY 2在模型层面的效果是一样的。但是 permit 不允许传递值,除非明确指定键。所以 c1c2 将不被允许,除非像

这样明确指定
params.permit(:id, answers_attributes: [c1: [:id, :content], c2: [:id, :content]])

这真是让人头疼。