Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Undefined method `concat'" on "devise_parameter_sanitizer.permit" #4477

Closed
marianatuma opened this issue Mar 24, 2017 · 14 comments
Closed

"Undefined method `concat'" on "devise_parameter_sanitizer.permit" #4477

marianatuma opened this issue Mar 24, 2017 · 14 comments

Comments

@marianatuma
Copy link

marianatuma commented Mar 24, 2017

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.

@JustLey
Copy link

JustLey commented Mar 25, 2017

This looks like a deprecation error. What Rails version are you using?

@marianatuma
Copy link
Author

marianatuma commented Mar 27, 2017

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.

@JustLey
Copy link

JustLey commented Apr 9, 2017

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.

@tegon
Copy link
Member

tegon commented Dec 22, 2017

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!

@tegon
Copy link
Member

tegon commented Jan 11, 2018

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!

@tegon tegon closed this as completed Jan 11, 2018
@jerome-diver
Copy link

jerome-diver commented Nov 18, 2018

@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.

@nashby
Copy link
Collaborator

nashby commented Nov 19, 2018

@jerome-diver Can you please provide a sample application that reproduces the error?

@tegon tegon reopened this Nov 19, 2018
@tegon
Copy link
Member

tegon commented Dec 11, 2018

@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?

@tegon
Copy link
Member

tegon commented Dec 27, 2018

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!

@tegon tegon closed this as completed Dec 27, 2018
@jerome-diver
Copy link

yes, i'm still facing the same problem.
something wrong never resolved staying there... don't close before resolve please.

@tegon
Copy link
Member

tegon commented Dec 28, 2018

@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.

@jerome-diver
Copy link

jerome-diver commented Dec 28, 2018

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

@tegon
Copy link
Member

tegon commented Dec 28, 2018

@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.

@jerome-diver
Copy link

jerome-diver commented Dec 28, 2018

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

5 participants