Reputation: 87
I'm using strong parameters for my ShareOptions
controller, like so:
def share_option_params
params.require(:share_option).permit(:public_read, :team_read, :team_write)
end
As you can see, :share_option
is required, so when I test PUT with the attributes directly in a JSON body like this: { public_read: true }
, my test correctly fails because they're not nested under share_option
. Using binding.pry
, this is the output of share_option_params
:
<ActionController::Parameters {"public_read"=>"true", "format"=>:json, "controller"=>"api/share_options", "action"=>"update", "id"=>"553"} permitted: false>
However, this is not the case with my JS frontend where the same request is successful. There, I'm sending { public_read: true }
directly, not nested. In this case, it appears as if share_option
is automatically added, here the output of share_options_params
:
<ActionController::Parameters {"public_read"=>true, "format"=>:json, "controller"=>"api/share_options", "action"=>"update", "id"=>"332", "share_option"=>{"public_read"=>true}} permitted: false>
At this point, I'm suspecting that Rails is doing something behind the scenes. But it's not clear to me at all as to why this is happening.
Upvotes: 0
Views: 327
Reputation: 87
Turns out Rails allows you to omit the root element of your request when making correct JSON requests. In my case, my test wasn't encoding correctly as JSON, so this behavior wasn't occurring.
More information here: https://edgeguides.rubyonrails.org/action_controller_overview.html#json-parameters
[…] if you've turned on config.wrap_parameters in your initializer or called wrap_parameters in your controller, you can safely omit the root element in the JSON parameter. In this case, the parameters will be cloned and wrapped with a key chosen based on your controller's name. So the above JSON request can be written as […]
To avoid this going forward, I plan on wrapping my params in my helper method for tests:
def json_request(params)
{
params: params.to_json,
headers: { 'CONTENT_TYPE' => 'application/json' }
}
end
Upvotes: 1