On a rails 4.1.4 application some parameters are not processed by the model, presumably depending on their type. When making a POST request like the following, all parameters get processed correctly and the new recipe is saved to the database with the correct values in place:
POST /api/v0/recipes HTTP/1.1
Host: localhost:3000
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: f49d43b3-9007-9687-a24f-92e7e7c873bd
{"recipe":{"name":"Spaghetti Carbonara","description":"Catchy description", "body":"Steps here","preparation_time":200,"category_id":"1","ingredients_attributes":[{"food_id":2,"quantity":100,"unit":"g"}, {"food_id":2,"quantity":150,"unit":"g"}]}}
Notice that the value for preparation_time
is passed as an integer and the value for category_id
is passed as a string. However, when the value for preparation time is passed as a string, like the one for category_id
, validation fails, complaining that preparation_time
is required per the model's validation rules.
Here is the failing request:
POST /api/v0/recipes HTTP/1.1
Host: localhost:3000
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: 70500362-9573-8684-bdaf-8dd0a0b3b05d
{"recipe":{"name":"Spaghetti Carbonara","description":"Catchy description", "body":"Steps here","preparation_time":"200","category_id":"1","ingredients_attributes":[{"food_id":2,"quantity":100,"unit":"g"}, {"food_id":2,"quantity":150,"unit":"g"}]}}
And here is the log for that request, which shows that the preparation_time
parameter arrived correctly:
Started POST "/api/v0/recipes" for 10.0.2.2 at 2014-07-20 17:11:08 +0200
Processing by Api::V0::RecipesController#create as */*
Parameters: {"recipe"=>{"name"=>"Spaghetti Carbonara 2", "description"=>"Catchy description", "body"=>"Steps here", "preparation_time"=>"200", "category_id"=>"1", "ingredients_attributes"=>[{"food_id"=>2, "quantity"=>100, "unit"=>"g"}, {"food_id"=>2, "quantity"=>150, "unit"=>"g"}]}}
(0.2ms) begin transaction
Food Load (1.3ms) SELECT "foods".* FROM "foods" WHERE "foods"."id" = ? LIMIT 1 [["id", 2]]
CACHE (0.0ms) SELECT "foods".* FROM "foods" WHERE "foods"."id" = ? LIMIT 1 [["id", 2]]
Recipe Exists (0.4ms) SELECT 1 AS one FROM "recipes" WHERE "recipes"."name" = 'Spaghetti Carbonara 2' LIMIT 1
(0.2ms) rollback transaction
Completed 422 Unprocessable Entity in 44ms (Views: 0.3ms | ActiveRecord: 2.1ms)
The response contains an error message stating that the preparation_time
parameter is not set:
{"preparation_time":["can't be blank","is not a number"]}
The status is 422 Unprocessable Entity
.
The validation rules in place for category_id
and preparation_time
are exactly the same:
validates :preparation_time, presence: true, numericality: { only_integer: true, greater_than: 0 }
validates :category_id, presence: true, numericality: { only_integer: true, greater_than: 0 }
Why does this happen just with one parameter? Is it something I am missing? Is it a bug in rails?