JSON request not parsed into parameters

478 Views Asked by At

Having spent an afternoon googling and testing, I am convinced there is a piece of rails magic missing, but have no idea where it is.

I have a test that replicates the error seen in production.

Rails 4.2.11.13

Using the protected_attributes gem (so not a strong parameters issue)

I successfully send a json request to an api controller, but it only creates an empty version of the payment_allocation parameter.

Controller...

class Api::V1::PaymentAllocationsController < Api::ApiController
  def create
    p request.content_type
    p request.body.read
    p params
    p self._wrapper_options
  end
end 

The body of the request as seen in the controller...

"{\"amount\":123.33,\"transaction_type\":\"Transaction\",\"claim_number\":\"ABC-123\",\"resolved\":false,\"paid_on\":\"2000-01-01\"}"

The content type.... "application/json"

The resulting params object...

{"controller"=>"api/v1/payment_allocations", "action"=>"create", "payment_allocation"=>{}}

And I confirmed that all the necessary attributes are available to the options used by wrap_parameters

 <struct ActionController::ParamsWrapper::Options name="payment_allocation", 
format=[:json], 
include=["paid_on", "amount", "resolved", "claim_number", "transaction_type"], 
exclude=nil, klass=Api::V1::PaymentAllocationsController, 
model=PaymentAllocation(id: integer, paid_on: date, claim_number: string, transaction_type: string, amount: decimal, resolved: boolean)>

The wrap_parameters initializer is like so...

# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
ActiveSupport.on_load(:action_controller) do
  wrap_parameters format: [:json]
end

# Disable root element in JSON by default.
ActiveSupport.on_load(:active_record) do
  self.include_root_in_json = false
end

And I have confirmed that the initializer is being called.

So wrap_parameters has the right class, the right attributes, etc, but does not actually set the parameter values in payment_allocation.

My best is guess is that something can't parse the json string, but JSON.parse for the above string returns this...

{"amount"=>123.33, "transaction_type"=>"Transaction", "claim_number"=>"ABC-123", "resolved"=>false, "paid_on"=>"2000-01-01"}

Happy for any hints.

(BTW, I have an app with the same code in the same version of rails that does not have this issue.)

1

There are 1 best solutions below

0
On

Discovered the issue, or more correctly, my colleague did.

We are using Rails LTS to support some of our older applications and there is a configuration setting for LTS in the application.rb file.

We had this set initially as...

config.rails_lts_options = {
  default: :hardened
}

From the LTS docs, we learned that one of the effects of this setting is that it disables parsing JSON requests into parameters.

Changing the setting to...

config.rails_lts_options = {
  default: :compatible
}

Enables parsing JSON requests into parameters, which is what Rails does naturally. And things are working as desired.