Trevor Filter
Trevor Filter

Reputation: 117

Why isn't my Rails API saving anything to the database?

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

Answers (2)

Trevor Filter
Trevor Filter

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

Jorge de los Santos
Jorge de los Santos

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

Related Questions