Rails 7 allows permitting numeric params

Saeloun Logo

In Rails, strong params provide an interface
for protecting attributes from the end-user assignment.
We can specify required attributes
and neglect unnecessary attributes to be used in the Active model
mass assignment.
However, in Rails 6, there was an issue
with permitting nested hash with numeric keys.
Permit behavior was inconsistent
and confusing when nested hash contains integer keys.

Let’s understand this by an example.
Here, we have params with numeric keys.

params = ActionController::Parameters.new(
  person: {
    "0": {
      name: "Sam",
      email: "[email protected]"
    "1": {
      name: "John",
      email: "[email protected]"

params.require(:person).permit("0": [:name], "1": [:name]).to_h

# {"0"=>{"name"=>"Sam"}, "1"=>{"name"=>"John"}}

The params can be permitted as we did above.
This is what we want in most cases but issues arise when
we call permit directly on parent hash.


We can permit individual keys under numeric keys
by specifying them for each numeric key.

params.require(:person).permit("0": [:name], "1": [:email]).to_h

# {"0"=>{"name"=>"Sam"}, "1"=>{"email"=>"[email protected]"}}

It returns the keys that we specified individually for each numeric key.

However, when we call permit directly on parent hash i.e without using require,
the result is not the same anymore.

params.permit(person: {"0": [:name], "1": [:email]}).to_h

# {"person"=>{"0"=>{}, "1"=>{}}}


In Rails 7,
the issue with the permit method has been resolved.
Now, the permit behaves same as calling
on parent hash as calling on child hash.

We can see in the below example that
calling the permit method directly
on params gets the same result as first
calling require on params
and then permitting the required attributes.

params.require(:person).permit("0": [:name], "1": [:email]).to_h

# {"0"=>{"name"=>"Sam"}, "1"=>{"email"=>"[email protected]"}}

params.permit(person: {"0": [:name], "1": [:email]}).to_h

# {"person"=>{"0"=>{"name"=>"Sam"}, "1"=>{"email"=>"[email protected]"}}}

Check out this pull request to
know more about this change.

Source link

Leave a reply

Please enter your comment!
Please enter your name here