Thibaud Clement
Thibaud Clement

Reputation: 6897

Rails 4 + Devise: how to sanitize multiple new parameters?

Being fairly new to Rails, I am learning how to implement Devise.

To do so, I am following this Site Point tutorial by Ilya Bodrov-Krukowski, from March 26, 2015.

One of the things the tutorial teaches is how to create a registration form with an additional field: name.

After updating the relevant view, the author explains the following:

If you are using Rails with strong_params (which are enabled in Rails 4 by default), one more step is needed: the :name attribute has to be whitelisted.

and he recommends this code to do so:

before_action :configure_permitted_parameters, if: :devise_controller?

protected

def configure_permitted_parameters
  devise_parameter_sanitizer.for(:sign_up) << :name
  devise_parameter_sanitizer.for(:account_update) << :name
end

This is working just fine... but my problem is that I want to add more than one new field to the registration form.

Indeed, I want my registration form to require users to type in their first_name, last_name and company_name.

I updated my view and I do get the right fields in the form.

However, so far, I have not been able to whitelist these three attributes.

I tried to do:

before_action :configure_permitted_parameters, if: :devise_controller?

    protected

    def configure_permitted_parameters
      devise_parameter_sanitizer.for(:sign_up) << :first_name, :last_name, :company_name
      devise_parameter_sanitizer.for(:account_update) << :first_name, :last_name, :company_name
    end

But when I do so, I get an unexpected "," error.

I also tried:

before_action :configure_permitted_parameters, if: :devise_controller?

    protected

def configure_permitted_parameters
  devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:first_name, :last_name, :company_name) }
  devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:first_name, :last_name, :company_name) }
end

But I am afraid this is now REPLACING the default Devise attributes (email, password and password confirmation — and maybe some other attributes I am forgetting) instead of simply ADDING my new attributes to the list.

So, my question is: how can I whitelist first_name, last_name and company_name without overriding Devise default attribute?

Upvotes: 1

Views: 1755

Answers (1)

joshua.paling
joshua.paling

Reputation: 13952

Try putting square brackets around the array of items you're adding, and using it with a keys: key and permit instead of for:

[https://github.com/plataformatec/devise#strong-parameters 4.2.x 4.3.x

def configure_permitted_parameters
  devise_parameter_sanitizer.permit(:sign_up, keys: [:first_name, :last_name, :company_name])
  devise_parameter_sanitizer.permit(:account_update, keys: [:first_name, :last_name, :company_name])
end

The shovel operator << adds a single item only to an array, which is why devise_parameter_sanitizer.for(:sign_up) << :first_name, :last_name, :company_name gives you an error, since you're passing it 3 arguments, not one.

The + operator adds two arrays together, which is what I've done in the snippet above.

Personally though, I'd just be using the last example you gave (passing in a block) and manually including all the fields you want, including devise's defaults, if you're using them.

UPDATE: In your comment, you asked: "do you know where I can find a list — of Devise's defaults parameters?"

They're defined in the github repo here: https://github.com/plataformatec/devise/blob/master/lib/devise/parameter_sanitizer.rb#L83-L92

And here's the relevant code:

def attributes_for(kind)
  case kind
  when :sign_in
    auth_keys + [:password, :remember_me]
  when :sign_up
    auth_keys + [:password, :password_confirmation]
  when :account_update
    auth_keys + [:password, :password_confirmation, :current_password]
  end
end

So, it's your auth_keys (usually email or username or whatever you've configured there) plus password and password_confirmation.

But devise's defaults are actually besides the point. You're deciding what parameters you want/need to allow through for your own sign up form, and for your own account update action. If they happen to overlap with Devise's defaults, fine, and if they don't, that's absolutely fine too.

Upvotes: 7

Related Questions