Heading image for post: Wrap Parameters Without Changing Markup

Wrap Parameters Without Changing Markup

Profile picture of Matt Polito

While updating logic that caused a POST with a JSON body to change into a POST as multipart/form-data, I ran into an issue where the Rails controller was expected params in a nested way. Sure, I could change my inputs to have a different name that would cause the nested structure, but that was changing logic down the line.

Rails was wrapping the incoming parameters automatically since the prior request was of 'Content-Type': 'application/json'. Well, I'd really like this same behavior on my new request as it would solve my current conundrum.

Turns out ActionController has a method that can help out with that... the aptly named wrap_parameters method.

In my case, the name I needed was the same as the controller so I could use this:

class FooController < ApplicationController
  wrap_parameters format: %i[mutlipart_form json]
end

This produces a params payload like so:

ActionController::Parameters {
  "account_id_eq"=>"",
  "date_gteq"=>"2017-11-01",
  "controller"=>"foo",
  "foo"=>{
    "account_id_eq"=>"",
    "date_gteq"=>"2017-11-01"
  }
>

Notice how the params come in as posted initially as well as a duplicate copy of them wrapped in my desired namespace.

Hooray! My old functionality is back with minimal changes needed.

Now luckily, for me, the wrapper name was the same as my controller. That won't always be the case, but wrap_parameters still has got you covered:

class FooController < ApplicationController
  wrap_parameters "bar", format: %i[mutlipart_form json]
end

This produces a params payload like so:

ActionController::Parameters {
  "account_id_eq"=>"",
  "date_gteq"=>"2017-11-01",
  "controller"=>"foo",
  "bar"=>{
    "account_id_eq"=>"",
    "date_gteq"=>"2017-11-01"
  }
>

Another relatively simple method to have in the back of your mind when this problem inevitably strikes again!

Photo by dylan nolte

More posts about Rails. Ruby