Failure/Error: devise_parameter_sanitizer.permit(:sign_up, keys: [:nome, :password, :password_confirmation, :cnpj, :razao_social, :nome_fantasia, :email, :tipo_entidade_id])
NoMethodError:
undefined method `concat' for #<Proc:0x0055ca9fb2d850>
Did you mean? concern
I'm using Rspec to test a custom RegistrationsController, and I haven't written a view yet, so I haven't tested this outside Rspec.
The full controller:
class Users::RegistrationsController < Devise::RegistrationsController
before_action :configure_sign_up_params, only: [:create]
# before_action :configure_account_update_params, only: [:update]
# POST /resource
def create
user_params = sign_up_params[:user_params]
entidade_params = sign_up_params[:entidade_params]
if !(User.exists?(email: user_params[:email]) || Entidade.exists?(cnpj: entidade_params[:cnpj]))
@entidade = Entidade.new(entidade_params)
@entidade.data_validade = 30.days.from_now
if @entidade.save
@user = User.new(user_params)
@user.entidade_id = @entidade.id
if @user.save
flash[:notice] = 'Usuario criado com sucesso.'
redirect_to root_path
end
end
end
end
protected
# If you have extra params to permit, append them to the sanitizer.
def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up, keys: [:nome, :password, :password_confirmation, :cnpj, :razao_social, :nome_fantasia, :email, :tipo_entidade_id])
end
end
Am I doing something wrong?
Edit: just tested manually, error also happens.
This looks like a deprecation error. What Rails version are you using?
Rails is on 4.2.1, Ruby is on version 2.3.1p112 and devise is also on 4.2.1.
Sorry I took so long to reply!
EDIT: Tried updating ruby to 2.4.0p0 and rails to 4.2.8, but the error persists.
I think I see the problem. The action that should be passed must be the action your controller is trying to execute, which, in your case, is 'create'. From lib/devise/parameter_sanitize:84 :
# * +action+ - A +Symbol+ with the action that the controller is
# performing, like +sign_up+, +sign_in+, etc.
So I suggest you change the :sign_up symbol for :create, or the action name to 'sign_up' (since you are overwriting the RegistrationsController) and see where it goes.
Remember that you can call 'super' if you need only to append some logic to the existing RegistrationsController#sign_up action. So, another alternative would be to change the action name to 'sign_up', check what Devise is already doing for you and complementing it with your own logic + a 'super' call for the ancestor method.
I hope my comment helps :D also, sorry for the delayed response, pretty busy lately.
Hello @marianatuma, thanks for your report.
Can you provide us a sample application that reproduces the issue in isolation?
That would help us find the issue.
Thank you!
I'm closing this issue because it has not had recent activity.
If you're still facing this on the latest version, please open a new one with all the information requested in the template.
Thank you!
@marianatuma did you find a solution ?
@tegon i have the same problem.
Rails-5.2.1 installed with ruby-2.5.1
My initial state is to have an empty user table inside my database (no user registred)... i want to create one by sign_up. I added some columns in my database (username, family_name, second_name), then add them to this method "signup_params" inside app/controller/users/registrations_controller.rb file (i understand that it is the way to add these parameters to be valid with the other original ones from default devise one's).
And get the same error.
I think that 'concat' is call from somewhere for add (concat) these 3 entries to the default one to be "white-listed". These entry are ":username, :family_name, :second_name". I tryed with 'username', 'family_name', 'second_name' but same result.
I searched for 'concat' code inside devise:
and find th eone used (i think) inside parameter_sanitizer.rb at line 117:
@permitted[action].concat(keys)
2 other files use this method for URL_HELPER and from authenticable.rb also...
but i not understand the error message and what i'm supposed to do for fix this problem.
I hope @marianatuma (if she find) to be able to share and help with this, or maybe someone other has an idea ?
thank you for your help.
@jerome-diver Can you please provide a sample application that reproduces the error?
@jerome-diver I created a new application and included a name field in the users table and in the sign up form, and it worked. I'm including a zip file with the application so that you can check it out.
concat-params.zip
Can you send us a sample application that reproduces that error?
I'm closing this issue because it had no recent activity.
If you're still facing this on the latest version, please open a new one with all the information requested in the template.
Thank you!
yes, i'm still facing the same problem.
something wrong never resolved staying there... don't close before resolve please.
@jerome-diver Did you see the test app I sent you? I wasn't able to reproduce the issue, so I've asked for a sample application that does so I can see what's happening, but I didn't get any response, that's why I closed the issue.
oh yes, sorry.
Well, i can give you my open code (it is a test application anyway). You can try it and see.
That's strange because i don't know where the problem is from (so difficult for me to create a specific test case only for this problem, i think if i could do it i done it). It is difficult because it is not the forst time i use devise but it is the first time i see this problem (and first time to do code with Rails on version 5). Also this code was running perfectly on an other one computer (the code is not online on a server actually, because i test things to find the best componant who can work fine together). And then i'm not at home in Thailand and from my laptop (same OS), it seems to be buggeg.
Tell me if you have an idea where the problem can come from...
my bitbucket open source code
@jerome-diver I took a look at your code and it turns out there are a couple of changes to be done in order for this to work:
First, you're calling Devise::ParameterSanitizer#permit two times for the same action (:sign_up): in ApplicationController and in Users::RegistrationsController. This is unnecessary - and it's also what's causing the issue.
There are basically two ways to permit a list of keys using Devise::ParameterSanitizer#permit: using the keys parameter or by passing a block. Internally, the attributes are kept in a hash of arrays, with one key for each action: sign_in, sign_up and account_update. The default looks like this:
{:sign_in=>[:password, :remember_me], :sign_up=>[:password, :password_confirmation], :account_update=>[:password, :password_confirmation, :current_password]}
Your application is first passing a block - in ApplicationController - and later trying to add more attributes using the keys parameter - in Users::RegistrationsController.
So what happens is that in the second call, Devise tries to add keys to a Proc.
# app/controllers/application_controller.rb
devise_parameter_sanitizer.permit(:sign_up) { |p| p.permit(:username, :familly_name, :second_name, :email, :password, :password_confirmation) }
# @permitted[:sign_up] is now a Proc
<Proc:0x00007f9f9ff24630@/Users/tegon/src/public/aquaworks/app/controllers/application_controller.rb:15>
# app/controllers/users/registrations_controller.rb
devise_parameter_sanitizer.permit(:sign_up, keys: [:username, :familly_name, :second_name])
@permitted[:sign_up].concat([:username, :familly_name, :second_name]) # error
So basically what you have to do is remove one of the calls - I'd say to remove the ApplicationController one since this is a responsibility of Users::RegistrationsController. But if you go with that option, you'll have to rename the methods sign_up_params and account_update_params. They exist in the superclass Devise::RegistrationsController and overriding them cause issues. I suggest you rename them to configure_sign_up_params and configure_ account_update_params.
I hope this helps.
@tegon i just read your explication and this make sens, i understand (you explication is perfect also). Fantastic, i'm very happy because i was stick on that for long time now and really, you take time to explain clearly what"s happening.
I correct my errors and now for sure, it is working perfectly. That was logic, i didn't know the way it works, i thinking it was over loading the method class (i was thinking wrong) and yes, it was one or the other and not together in application controller and user_registration controller... my bad.
Thank you very much for your great and useful help @tegon.
Most helpful comment
@jerome-diver I took a look at your code and it turns out there are a couple of changes to be done in order for this to work:
First, you're calling
Devise::ParameterSanitizer#permittwo times for the same action (:sign_up): inApplicationControllerand inUsers::RegistrationsController. This is unnecessary - and it's also what's causing the issue.There are basically two ways to permit a list of keys using
Devise::ParameterSanitizer#permit: using thekeysparameter or by passing a block. Internally, the attributes are kept in a hash of arrays, with one key for each action:sign_in,sign_upandaccount_update. The default looks like this:Your application is first passing a block - in
ApplicationController- and later trying to add more attributes using thekeysparameter - inUsers::RegistrationsController.So what happens is that in the second call, Devise tries to add keys to a
Proc.So basically what you have to do is remove one of the calls - I'd say to remove the
ApplicationControllerone since this is a responsibility ofUsers::RegistrationsController. But if you go with that option, you'll have to rename the methodssign_up_paramsandaccount_update_params. They exist in the superclassDevise::RegistrationsControllerand overriding them cause issues. I suggest you rename them toconfigure_sign_up_paramsandconfigure_ account_update_params.I hope this helps.