Rails Rest-Post hash parameter not written
I am creating my first REST API using Rails and I have a simple question that I cannot solve.
Basically, I cannot write the params hash to the database from the http request PUSH
.
I have the following custom controller in the Api namespace with a create action.
class Api::UserController < ApplicationController
http_basic_authenticate_with :name => "test", :password => "test"
skip_before_action :verify_authenticity_token
def create
@user = User.create(params[:user])
respond_to do |format|
if @user.save
format.json{render json: @user, status: :created, location: @user} #render create full response
else
format.json{render json: @user.errors, status: :unprocessable_entity}
end
end
end
end
The route of this action
POST /api/user(.:format) api/user#create{:format=>"json"}
The custom model has a name and an address bar that is not contained.
To test the REST call I am setting up firefox plugins RESTeasy
and RESTclient
with this urlhttp://localhost:3000/api/user/
and this authority {"name": "timoteo", "address": "berlin"}
So far so good. Now after submitting this package, Webrick gives me this output:
Started POST "/api/user" for ::1 at 2015-08-03 17:06:50 +0200
Processing by Api::UserController#create as JSON
Parameters: {"name"=>"timoteo", "address"=>"berlin"}
(1.2ms) BEGIN
SQL (0.6ms) INSERT INTO "users" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id" [["created_at", "2015-08-03 15:06:50.646169"], ["updated_at", "2015-08-03 15:06:50.646169"]]
(42.8ms) COMMIT
(0.3ms) BEGIN
(0.3ms) COMMIT
Completed 201 Created in 66ms (Views: 1.4ms | ActiveRecord: 48.1ms)
neglecting the two parameters and an empty empty entry like this is stored in the database (also the REST clients show me the same)
{"id":19,"name":null,"address":null,"created_at":"2015-08-03T15:06:50.646Z","updated_at":"2015-08-03T15:06:50.646Z"}
Can someone give me a hint what might have gone wrong along the way. I'm guessing it's something with the params hash, but I couldn't figure it out yet.
source to share
Add confirmation to your model:
class User < ActiveRecord::Base
validates_presence_of :name
validates_presence_of :address
end
This will prevent saving the entry with empty attributes.
Then change the call #save
to #persisted?
in your controller (since the entry is created immediately after the call #create
, it is already saved or triggered)
if @user.persisted?
format.json{render json: @user, status: :created, location: @user} #render create full response
else
format.json{render json: @user.errors, status: :unprocessable_entity}
end
UPD . You can also take advantage of the whitelisting parameters you accept:
@user = User.create(params.require(:name, :address))
This way, Rails will respond with an error indicating that the parameter is missing and will not assign any other attributes to the user (which you don't want to assign).
source to share
Your options { "name": "timoteo", "address": "berlin" }
are wrong when your user creation@user = User.create(params[:user])
You should be more like: { "user": { "name": "timoteo", "address": "berlin" } }
because you are accessing params[:user]
, so the user attributes should belong to the user section of your options.
Adding checks can help if it is incorrect to save a user without a name and address.
class User < ActiveRecord::Base
validates :name, presence: true
validates :address, presence: true
# etc...
end
source to share