Strong parameters with nested hash

天大地大妈咪最大 提交于 2019-12-03 18:01:17

It's done with syntax like:

answers_attributes: [:id, :content]

The problem is the keys you are using in the answers_attributes. They are expected to be the ids of the answers_attributes or in the case of new records 0.

Changing these gives your expected outcome:

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"}}}

Edit: It appears that 0 is not the only key, I mean what if you have two new records. I use nested_form and it appears to use a very long random number.

Your answers_attributes contains c1 and c2 which are not permitted. http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

WAY 1: You can pass the nested attributes as array of hashes.

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

Now params.permit(:id, answers_attributes: [:id, :content]) gives

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

WAY 2: You can pass as hash of hashes like

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

Both WAY 1 and WAY 2 have the same effect in the model level. But permit doesn't allow the values to pass unless the keys are explicitly specified. So c1 and c2 will not be permitted unless explicitly specified like

params.permit(:id, answers_attributes: [c1: [:id, :content], c2: [:id, :content]])

which is really a pain in the ass.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!