How to permit nested parameters in Rails

flaviabastos

Flávia Bastos

Posted on September 30, 2020

How to permit nested parameters in Rails

The context

Rails 5 introduced a big change in how it handles ActionController::Parameters (the parameters that you get on your Controllers): before Rails 5, if you called your params you would get a hash back and after Rails 5, you get a ActionController::Parameters object. You can see that by calling params.inspect and if you call .to_h on these parameters you should be good to go.

However, you might get an empty hash when calling .to_h on some parameters because they were not explicitly permitted – see the result of inspecting my params (note the “permitted: false” at the very end):

<ActionController::Parameters {"friends" => {"park" => "Doggoland", "dogs"=>[{"id"=>73, "name"=>"Milou", "household"=>"Tintin"}, {"id"=>74, "name"=>"Snoopy", "household"=>"Charlie Brown"}]}} permitted: false>
Enter fullscreen mode Exit fullscreen mode

Permitting params was showing up back in Rails 4 when Strong Parameters were introduced as part of security features and this blog post goes through some examples of why just calling .to_h might be an issue now that Rails 5 returns objects instead.

Permitting parameters

One good way to permit some parameters is by creating a private helper function in your controller that will explicitly permit the parameters you want:

private def nice\_params params.permit(:id, :name, :email).to\_h end
Enter fullscreen mode Exit fullscreen mode

When accessing your params, instead of params[:name], you use nice_params[:name].

Permitting nested parameters

Things get a little more complicated when you have a nested data structure. The documentation only gets one level deep and I had something more complicated than that. Let’s use the following as an example:

{"friends" => { "park" => "Doggoland", "dogs"=>[{"id"=>73, "name"=>"Milou", "household"=>"Tintin"}, {"id"=>74, "name"=>"Snoopy", "household"=>"Charlie Brown"}] } }
Enter fullscreen mode Exit fullscreen mode

My nice_params function looks like this:

def nice\_params params.permit( friends: [:park, dogs: [:id, :name, :household]] ).to\_h end
Enter fullscreen mode Exit fullscreen mode

One very important thing to notice is that the nested list must be placed last!

I hope this helps someone else with deep nested params. 😅


If you found this helpful, let me know on Twitter!

The post How to permit nested parameters in Rails_ was originally published at _flaviabastos.ca

💖 💪 🙅 🚩
flaviabastos
Flávia Bastos

Posted on September 30, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

How to upgrade Rails
howto How to upgrade Rails

March 26, 2020