Reputation: 676
I have a Rails 5.2 app built as API only. I am using Postman to test the endpoints. Currently, I am wrapping all of my JSON POSTS with the root element in order to get it to pass the 'strong parameters'. According to the Rails docs, however, with wrap_parameters
set to accept JSON, I shouldn't have to be doing this, however, my POSTs fail if I don't. What am I doing wrong?
# users_controller.rb
class UsersController < ApplicationController
before_action :set_user, only: [:show, :update, :destroy]
.....
# POST /users
def create
@user = User.new(user_params)
if @user.save
render json: @user, status: :created, location: @user
else
render json: @user.errors, status: :unprocessable_entity
end
end
.....
private
.....
# Only allow a trusted parameter "white list" through.
def user_params
params.require(:user).permit(:email, :password, :is_admin, :is_agent)
end
end
# config/initializers/wrap_parameters.rb
ActiveSupport.on_load(:action_controller) do
wrap_parameters format: [:json]
end
If I wrap the JSON in a user
it works just fine, however, according to the Rails docs, I shouldn't have to do that.
http://api.rubyonrails.org/v5.2.0/classes/ActionController/ParamsWrapper.html
I have tried adding wrap_parameters User
and wrap_parameters :user
and wrap_parameters format: [:json]
directly to the users_controller.rb
but that doesn't do anything.
What am I doing wrong?
Upvotes: 7
Views: 6018
Reputation: 676
I figured it out. I had to add wrap_parameters :user, include: %i[email password is_admin is_agent]
to the Users controller like so:
# users_controller.rb
class UsersController < ApplicationController
before_action :set_user, only: [:show, :update, :destroy]
wrap_parameters :user, include: %i[email password is_admin is_agent]
.....
# POST /users
def create
@user = User.new(user_params)
if @user.save
render json: @user, status: :created, location: @user
else
render json: @user.errors, status: :unprocessable_entity
end
end
.....
private
.....
# Only allow a trusted parameter "white list" through.
def user_params
params.require(:user).permit(:email, :password, :is_admin, :is_agent)
end
end
I still don't fully understand why, but, it works. The docs imply this should be happening automagically through the wrap parameters module.
Upvotes: 5
Reputation: 2610
This is because of the parameter whitelisting.
def user_params
params.require(:user).permit(:email, :password, :is_admin, :is_agent)
end
Here , user key is required. As per the security point of view, its a good feature in RoR to whitelist the parameters
If you write only params.permit(:email, :password, :is_admin, :is_agent)
, then you same request will work but removing the user object is not recommended.
Upvotes: 0