I have a field otp_set_up, which in the company_user model is allowed to be "true" or "false".
There is a use case where a sys admin user can reset this field to "false".
While the field can be set to "true" through code, NO user can set it to "true" via a form edit etc.
I haven't added to it the validation in the model since it can be "true" or "false".
I have the following code in a params method specific to an update in the controller before the params.require .permit bit:
if curr_company_user.is_sys_admin? && curr_company_user.can_crud_company_users? && params[:id].to_i != curr_company_user.id
params[:company_user] = params[:company_user].except(:otp_set_up) if params[:company_user][:otp_set_up] == true
params.require(:company_user).permit(:otp_setup, etc. etc....
elsif etc. etc...
This works. A Sys admin user can not set otp_set_up to "true".
My question is:
Is this the best and correct way to do this in Rails? It seems a bit hacky to me, going through the params hash and removing a bit.
Is there a better / cleaner way?
Strong Parameters, aka Strong Params, are used in many Rails applications to increase the security of data sent through forms. Strong Params allow developers to specify in the controller which parameters are accepted and used.
The permit method returns a copy of the parameters object, returning only the permitted keys and values.
Specifically, params refers to the parameters being passed to the controller via a GET or POST request. In a GET request, params get passed to the controller from the URL in the user's browser.
params[:id] is meant to be the string that uniquely identifies a (RESTful) resource within your Rails application. It is found in the URL after the resource's name.
delete_if
cleans it up. Still a bit hacky, but slightly less so : )
params.require(:company_user).permit(:otp_setup).delete_if do |key, val|
key == 'otp_setup' && val == true
end
This leaves the original params
object intact.
There isn't a built in way to do this. It looks like there used to be but no more https://github.com/rails/strong_parameters/issues/167
delete_if
is defined on Hash
in the core library, so it is probably the best way to do it in Ruby and by extension in Rails in the absence of a built in method.
I thought it was an interesting idea, so I wrote a small gem called allowable for this type of use case. It will add a few methods to Hash
and ActionController::Parameters
: #allow
, #allow!
, #forbid
and #forbid!
You would use it like this
params.require(:company_user).permit(:otp_setup).forbid(otp_setup: [true])
# or
params.require(:company_user).permit(:otp_setup).allow(otp_setup: [false])
You can specify a single value or an array of values, and it doesn't mutate the original params
object
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With