具有嵌套哈希的强参数
Strong parameters with nested hash
我有以下参数,无法使强参数起作用。
这是我的基本代码,为简单起见,可在 Rails 控制台中运行:
json = {
id: 1,
answers_attributes: {
c1: { id: "", content: "Hi" },
c2: { id: "", content: "Ho" }
}
}
params = ActionController::Parameters.new(json)
我读过的所有内容都说以下应该有效,但它只给了我 id
和 answers_attributes
:
的空散列
params.permit(:id, answers_attributes: [:id, :content])
=> { "id"=>1, "answers_attributes"=>{} }
如果我改为手动列出 c1
和 c2
(如下所示)它会起作用,但这真的很愚蠢,因为我不知道用户会提供多少答案,这是很多重复:
params.permit(:id, answers_attributes: { c1: [:id, :content], c2: [:id, :content] })
=> {"id"=>1, "answers_attributes"=>{"c1"=>{"id"=>"", "content"=>"Hi"}, "c2"=>{"id"=>"", "content"=>"Ho"}}}
我尝试用 0
和 1
替换 c1
和 c2
,但我仍然必须手动提供 0
和 1
在我的许可声明中。
如何允许未知长度的嵌套属性数组?
使用如下语法完成:
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 1和WAY 2在模型层面的效果是一样的。但是 permit
不允许传递值,除非明确指定键。所以 c1
和 c2
将不被允许,除非像
这样明确指定
params.permit(:id, answers_attributes: [c1: [:id, :content], c2: [:id, :content]])
这真是让人头疼。
我有以下参数,无法使强参数起作用。
这是我的基本代码,为简单起见,可在 Rails 控制台中运行:
json = {
id: 1,
answers_attributes: {
c1: { id: "", content: "Hi" },
c2: { id: "", content: "Ho" }
}
}
params = ActionController::Parameters.new(json)
我读过的所有内容都说以下应该有效,但它只给了我 id
和 answers_attributes
:
params.permit(:id, answers_attributes: [:id, :content])
=> { "id"=>1, "answers_attributes"=>{} }
如果我改为手动列出 c1
和 c2
(如下所示)它会起作用,但这真的很愚蠢,因为我不知道用户会提供多少答案,这是很多重复:
params.permit(:id, answers_attributes: { c1: [:id, :content], c2: [:id, :content] })
=> {"id"=>1, "answers_attributes"=>{"c1"=>{"id"=>"", "content"=>"Hi"}, "c2"=>{"id"=>"", "content"=>"Ho"}}}
我尝试用 0
和 1
替换 c1
和 c2
,但我仍然必须手动提供 0
和 1
在我的许可声明中。
如何允许未知长度的嵌套属性数组?
使用如下语法完成:
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 1和WAY 2在模型层面的效果是一样的。但是 permit
不允许传递值,除非明确指定键。所以 c1
和 c2
将不被允许,除非像
params.permit(:id, answers_attributes: [c1: [:id, :content], c2: [:id, :content]])
这真是让人头疼。