How to permit nested parameters in Rails

rails web development

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 an 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>

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

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

My nice_params function looks like this:

def nice_params
  params.permit(
    friends: [:park, dogs: [:id, :name, :household]]
  ).to_h
end

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 would like to take your Ruby skills to the next level, check out the book The Well-Grounded Rubyist. (Please note that I get commissions for purchases made through this link at no extra cost to you.)


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

The post How to permit nested parameters in Rails was originally published at flaviabastos.ca

Related Posts