Strong Parameters with Nested Hash

Rails - Strong Parameters - Nested Objects

As odd as it sound when you want to permit nested attributes you do specify the attributes of nested object within an array. In your case it would be

Update as suggested by @RafaelOliveira

params.require(:measurement)
.permit(:name, :groundtruth => [:type, :coordinates => []])

On the other hand if you want nested of multiple objects then you wrap it inside a hash… like this

params.require(:foo).permit(:bar, {:baz => [:x, :y]})


Rails actually have pretty good documentation on this: http://api.rubyonrails.org/classes/ActionController/Parameters.html#method-i-permit

For further clarification, you could look at the implementation of permit and strong_parameters itself: https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/strong_parameters.rb#L246-L247

Strong parameters with nested hash

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.

Nested params with Strong Parameters

you have to white list all the possible values for owners

params.require(:area).permit(:name, :project_id, owners: [step2: [], color: [], step2: [], step3: []])

ok have you tried this for dynamic content with rails 5 ?

params.require(:area).permit(:name, :project_id, :owners => {})

How can I store random nested variables with strong params methods in Rails?

ActionController::Parameters does not have a "wildcard" syntax to allow any nested hash keys. But it does have #permit! which is an acknowledgement that strong parameters is not the solution for every possible problem.

permit! completely circumvents whitelisting by setting the permitted attribute on the ActionController::Parameters instance.

It will also set the permitted attribute on any nested instances of ActionController::Parameters - ie nested hashes in the parameters.

This is a very sharp tool which should be used with care.

In this case you might want to just use it on the nested attributes:

params.permit(:name, :age).merge(
books: params.dup.permit!.fetch(:books, [])
)

Permitting nested arrays using strong params in Rails

I believe the only way to work with nested parameters is to permit them as an array of hashes or use only scalar values inside the array.

According to the documentation:

To declare that the value in params must be an array of permitted scalar values map the key to an empty array:

params.permit(:id => [])

You can also use permit on nested parameters, like:

params.permit(:name, {:emails => []}, :friends => [ :name, { :family => [ :name ], :hobbies => [] }])

Your case with flattened values:

> ActionController::Parameters.new(filter: ['a', 1,2]).permit(filter: [])
=> <ActionController::Parameters {"filter"=>["a", 1, 2]} permitted: true>

With an array of hashes:

> ActionController::Parameters.new(filter: [{param1: 'a', param2: [1,2]}]).permit(filter: [:param1, param2: []])
=> <ActionController::Parameters {"filter"=>[<ActionController::Parameters {"param1"=>"a", "param2"=>[1, 2]} permitted: true>]} permitted: true>


Related Topics



Leave a reply



Submit