Question

I do POST http://0.0.0.0:3000/clients with the following request payload:

{"name": "David Smith", "email": "david@site.com"}

Both Firefox and Chrome clearly show that this is the payload.

But, in the Rails logs I see:

Started POST "/api/clients" for 127.0.0.1 at 2014-01-05 20:59:52 +1100 Processing by ClientsController#create as HTML Parameters: {"name"=>"David Smith", "email"=>"david@site.com", "client"=>{"name"=>"David Smith", "email"=>"david@site.com"}}

Indeed, if I print out params in ClientsController#create, I see that it contains the key client.

How does the "client"=>{"name"=>"David Smith", "email"=>"david@site.com"} part become part of params? Why Rails messing with params?

I use Rails 4.0.2.


The request is made using AngularJS:

ClientsNewCtrl = ['$scope', '$http', '$q', ($scope, $http, $q) ->
  $scope.client =
    name: ''
    email: ''

  $scope.createNewClient = ->
    defer = $q.defer()

    $http.post('/api/clients', $scope.client).success ->
      console.log 'Success!'
      defer.resolve()
    .error (errors, status) ->
      errors = ["Couldn't create the client."] if status != 422
      console.log errors
      defer.reject(errors)

    defer.promise
]

Here is the example that I created to demonstrate the issue: https://github.com/moroshko/rails-params

  1. rails s
  2. Go to http://0.0.0.0:3000
  3. Open browser's console to observe the request
  4. Enter name, email and click Create
  5. Check out Rails logs to see that params have the extra client key
Was it helpful?

Solution

Indeed, Rails messing with request params as specified by default in config/initializers/wrap_parameters.rb:

ActiveSupport.on_load(:action_controller) do
  wrap_parameters format: [:json] if respond_to?(:wrap_parameters)
end

To stop this behavior, one could do:

ActiveSupport.on_load(:action_controller) do
  wrap_parameters format: [] if respond_to?(:wrap_parameters)
end

Relevant info:

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top