Rails permit nested hash attributes Rails permit nested hash attributes json json

Rails permit nested hash attributes


If you want to permit a key having an array of permitted scalar values, then simply map the key to an empty array:

params.permit(key: [])

The permitted scalar types are String, Symbol, NilClass, Numeric, TrueClass, FalseClass, Date, Time, DateTime, StringIO, IO, ActionDispatch::Http::UploadedFile, and Rack::Test::UploadedFile

So when an array contains some non-scalar values like a hash, then you have to go further by permitting the nested keys too in the array.

Say, you have the following structure:

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

then the permission goes in this way:

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

Now let's assume your case looks like:

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

the permission will be:

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

To automate this, lets assume details has 5 attributes with permitted scalar values and 3 more array attributes that also have only scalar values.

First pluck the 5 non-array keys of details:

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

Next the 3 array keys inside details:

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

Now the details_keys will be ready by:

details_keys = non_array_keys << array_keysdetails_keys.flatten!

Final permission will look like:

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

If the nested arrays would contain non-scalar values, then I guess you have got enough idea by this point on how to adapt to your changes!

DISCLAIMER: this automation is not appreciated because, instead of doing all these, a simple invocation of params.require(:user).permit! would suffice. But this marks the :user parameters hash and any sub-hash of it as permitted and does not check for permitted scalars, anything is accepted. Extreme care should be taken when using permit!, as it will allow all current and future model attributes to be mass-assigned.

For details, I would strongly suggest to look at the Rails official guide covering Strong Parameters in details.


Adding empty array might work. You can switch off validation for nested attributes?! Are you creating dynamic random input fields which you do not control?