Reputation: 117
I'm building an app with Rails 4.1 that has a Users controller and a separate API controller for getting and posting basic user data at /v1/users
(will be served at a dedicated subdomain in production).
My API::V1:UsersController inherits from ActionController::Base and has the following create method:
# POST /v1/users
def create
@user = User.create(params[:user])
if @user.save
render :json => @user
else
render :json => { :errors => @user.errors.full_messages }, :status => 422
end
end
In my main UsersController, the create method looks like this:
def create
@user = User.new(user_params)
@user.save
redirect_to @user
end
private
def user_params
params.require(:user).permit(:first_name, :last_name, :email, :birthdate)
end
...And routes.rb ties everything together like so:
namespace :api, :path => "/", defaults: { format: 'json' } do
namespace :v1 do
resources :users
end
end
resources :users
However, when I try to POST via curl or another script to http://localhost/v1/users
, with Content-Type: application/json, the new user object is returned in JSON, but nothing is saved to Postgres (I'm using UUID as primary key for the users table). The user record is created, but the hash is completely empty save for timestamps:
{
"id": "c63b559d-edf3-454d-bcb7-a0b8e5c04c10",
"first_name": null,
"last_name": null,
"email": null,
"birthdate": null,
"created_at": "2014-06-04T23:45:15.046Z",
"updated_at": "2014-06-04T23:45:15.046Z"
}
My console output in development.log looks like the following:
Started POST "/v1/users" for 127.0.0.1 at 2014-06-04 19:32:28 -0400
Processing by API::V1::UsersController#create as JSON
Parameters: {"{ \"email\": \"[email protected]\" }"=>nil}
[1m[36m (0.1ms)[0m [1mBEGIN[0m
[1m[35mSQL (0.3ms)[0m INSERT INTO "users" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id" [["created_at", "2014-06-04 23:32:28.105402"], ["updated_at", "2014-06-04 23:32:28.105402"]]
[1m[36m (0.9ms)[0m [1mCOMMIT[0m
[1m[35m (0.1ms)[0m BEGIN
[1m[36m (0.1ms)[0m [1mCOMMIT[0m
Completed 200 OK in 3ms (Views: 0.2ms | ActiveRecord: 1.4ms)
Is there something I'm missing here? It looks like the parameters aren't even being received by the create method, and they're certainly not making their way to psql. Any help would be appreciated!
Upvotes: 1
Views: 690
Reputation: 117
An alternative solution is to add the following line at the top of the API users controller (or base class):
wrap_parameters format: [:json, :xml]
This will nest the JSON parameters in a wrapper hash with an additional "name" key that takes the name of the controller (per the Rails 4 API).
Upvotes: 1
Reputation: 4633
The json has wrong format. Try this:
{"user":{
"first_name": "string",
"last_name": "string",
"email": "string",
"birthdate": "string",
}}
As long as the params.require(:user) is expecting the object name.
Rails JSON request is not parsed correctly into post parameters
Upvotes: 1