The ActionController::UnpermittedParameters
error occurs when a parameter that has been passed is not permitted in a create, an update, or a user-defined action.
In older versions of Rails, information about the unpermitted keys was provided in the logs only when an unpermitted parameter was found in a request. This did not provide enough information for the developers to understand which controller
and action
received the unpermitted parameters.
Raising the Unpermitted Parameters Error Makes for Easier Debugging
Let's say we have a user
who has a name
, an email
address, and a role
attribute, and only the name and email attributes are permitted.
requested_params = { user: { name: "Tony Stark", email: "[email protected]", role: "admin" } }
tempParams = ActionController::Parameters.new(requested_params)
tempParams.permit(user: [:name, :email])
But in the log, we only get:
Unpermitted parameter: :role
As seen in the log, only information about the unpermitted key is provided, with no information about the controller
or action
that actually received the unpermitted parameter. If the log files don't specify which parameters are causing the problem, it will be very hard for a programmer to pinpoint the error when dealing with production-level code.
How to Raise the Unpermitted Parameters Error in Ruby
The two best ways to raise the Unpermitted Parameters error are as follows:
1. Modifying the Config File
In order to raise the Unpermitted Parameters error, the ActionController::Parameters.action_on_unpermitted_parameters
field should be set to :raise.
We need to make changes in a config
file development.rb
by adding the below line to the config/environments/development.rb
:
config.action_controller.action_on_unpermitted_parameters = :raise.
This causes an unpermitted parameter to be passed and causes the ActionController::UnpermittedParameters
error to pop up.
params = ActionController::Parameters.new(a: "567", b: "506")
params.permit(:c)
For the above code, the below error will be raised:
ActionController::UnpermittedParameters: found unpermitted parameters: :a, :b
2. Adding Context to the Code
In the latest versions of Rails, the developer has the ability to specify the context with a controller, action, request,
and param
keys. This context will be included in the logging payload.
Now let's try to modify the above code to accept the context as a parameter:
context = { controller: self.class.name, action: action_name }
requested_params = { user: { name: "Tony Stark", email: "[email protected]", role: "admin" } }
tempParams = ActionController::Parameters.new(request_params, context)
tempParams.permit(user: [:name, :email])
In the log, we will have something like the following:
Unpermitted parameter: :role. Context: { controller: UsersController, action: create }
As we can see, the context is also logged, containing the controller
and action
keys. The big reason for including this context in our code is that it makes it easier to debug the code when dealing with large production-level applications and makes the programmer's task easier to comprehend.
How to Fix the Unpermitted Parameters Error in Ruby
We will be handling the Unpermitted Parameters error by using the rescue_from
clause. The rescue_from
clause takes a series of exception classes and a trailing with:
clause that takes the name of a method that will be called to handle the error.
Let’s examine the following block of code:
class Example < ApplicationController
wrap_parameters format: []
rescue_from ActionController::UnpermittedParameters, with: :handle_errors
def create
user = User.create!(user_data)
render json: user, status: :created
end
def update
user = User.find(params[:id])
user.update!(user_data)
render json: user
end
private
def user_data
params.permit(:password, :username)
end
def handle_errors
render json: { "Unpermitted Parameters found": params.to_unsafe_h.except(:controller, :action, :id, :username, :password).keys }, status: :unprocessable_entity
end
When the above code is run with unpermitted parameters, we get the following error message:
"Unpermitted Parameters found <keys creating the issue>".
We customize the error message using render
and whenever the error occurs, the method handle_errors
will be called. Using .to unsafe h
on parameters is crucial since it will turn all of the parameters into a standard Ruby hash. To ensure that all permitted arguments are excluded from the error message and only the parameters causing the error are displayed, an additional .except
has been introduced.
Giving context to code is an essential programming practice because it makes the programmer's task easier to analyze and troubleshoot while debugging.
Track, Analyze and Manage Errors With Rollbar
Managing errors and exceptions in your code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyze, and manage errors in real-time can help you proceed with more confidence. Rollbar automates error monitoring and triaging, making fixing Ruby errors easier than ever. Try it today!