Skip to main content

Devise: Add a select to my signup form

Rails • Asked by Alan Reid

Hi all, me again! haha
So i have got my app working as i want so far. All is good and i am picking up Rails really quickly thanks to GoRails.

I am however a little stuck, I can't seem to add in a select for my sign up form.

<%= f.select :is_brand, options_for_select(%w[true false]) %> This is adding in the select, however it does not seem to store the field when i submit. I am thinking its cause its not reference by devise as standard, and i have not got any devise registration controllers.

I basically want to have a select, with a list that says...

-- Select an option
-- I am a Brand  (value would be TRUE)
-- I am a Buyer  (value would be FALSE)

Then the/false would be stored as a bool in my DB, i have the DB all set up its just getting things to store.

Thanks in advance :D

Alan


Ok, so after reading up a load about Devise, i found they have made it easy to add in parameters on to the sign up forms.

You will need to create the devise controllers so check out the devise docs for details on how to do this.

Once created open up the registrations_controller.rb and scroll down the page to around line 46. Her you will see some code which is commented out.

# If you have extra params to permit, append them to the sanitizer.
# def configure_account_sign_up_params
#   devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute])
# end

Simply uncomment this, and add replace :attribute with the attribute you want stored to the DB! It's that easy! No need to write out your own sanitiser.

Now all thats left is to add in the fields you want added, so for me i wanted to add in a simple select, so i used the code below.
<%= f.select :is_brand, options_for_select([["I am a Brand", true], ["I am a Buyer", false]]) %>

I really hope this helps someone else out.


You know, it'd be kind of cool if someone added a generator to Devise that would allow you to add this code into ApplicationController automatically so you didn't have to look it up each time. Maybe someone should make a PR on Devise for this idea... hint hint 😉


haha @Chris ;) That would be my first PR. I would be keen to learn how to do that on such a large scale project, for example what would need to be included etc.


I would just open up an issue on their Github, ask if they'd be interested in the idea and if so, what are the things they'd like to see for it? code and document obviously, but does it need tests? that sorta thing. They're super helpful and that's basically what I did when submitting a suggestion for a feature on Devise previously.


Sounds cool, i will have a look see what others have written to get ideas :D Thanks


Be aware, things have changed!
It seems i had to now move this to my application_controller otherwise i kept getting Unpermitted parameters


Yeah, I think normally the devise_paramter_sanitizer stuff has to go in ApplicationController. Not entirely sure why but I guess because it's common and that doesn't require people to override the RegistrationsController.


What version of devise are you using to have had to move your permitted params into your ApplicationController?
Using Devise 4.2.0 ($ gem list | grep devise) I still have my sanitizers in controllers/registrations_controller.rb and no issue...

def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up) do |user|
            user.permit(:first_name, :last_name, :email, :password, :password_confirmation, :avatar, :time_zone)
        end
        devise_parameter_sanitizer.permit(:account_update) do |user|
            user.permit(:first_name, :last_name, :avatar, :email, :password, :password_confirmation, :current_password, :time_zone,
                                    contact_attributes: [:line_1, :line_2, :city, :state, :zip, :phone])
        end
  end

The only thing I don't like is having to declare the sanitizer for the :sign_up action and :account_update separately - it could probably be combined but I haven't dug into it yet (maybe not though??)


Jacob,

You should be fine putting it in RegistrationsController, my mistake. The main reason why they suggest ApplicationController being that not everybody overrides the RegistrationsController, so it's easier. It can definitely go in RegistrationsController too because that's really where it's being used.

I don't know about combining it, other than setting the arguments to a variable and passing in just the variable into both.


I am also using 4.2.0, I'm not sure why but i had to move it :/ i am also using rails 5.0.0.1 maybe this is why?

I am having issues with devise personally. Yeah its fantastic but its a pain cause i want to set the URL's to something different and i don't like how it deals with things. Might need to roll my own version of Auth soon i think.

Also I notice you have contact_attributes maybe you could shed some light on another post of mine? I need to save data into a different table. - https://gorails.com/forum/how-do-i-save-a-field-in-a-separate-table-when-using-devise
Maybe even let me know if there is a better way, maybe using joins?


What URL issues are you having?


Sure, I'll take a look. I learn as I go so if I've encountered it before then I can probably help!

You may have an issue with Rails 5, I'm still on 4.2.3 for the project I pulled that from. I did encounter your error a lot if I didn't have the proper before_filters set... so for mine its:

before_filter :configure_permitted_parameters, :only => [:create, :update]

lol i mentioned them before in another post.

I wanted to change things like user/edit to account but when you post the form, if there is an error it sends you to a different address.

I have the below set up for registrations, but when you post on /account and there is an error it redirects to /signup, ideally i want it to go back to /account. I have debugged and seen that its the PUT that is redirecting it - this is set in the url: registration_path(resource_name) part of the form.

# Registration
    get 'signup' => 'devise/registrations#new', :as => :new_user_registration
    post 'signup' => 'devise/registrations#create', :as => :user_registration
    get 'signup' => 'devise/registrations#cancel', :as => :cancel_user_registration
    get 'account' => 'devise/registrations#edit', :as => :edit_user_registration
    put 'signup' => 'devise/registrations#update'
    patch 'signup' => 'devise/registrations#update'
    delete 'signup' => 'devise/registrations#destroy'

I'm not 100% sure what you're trying to accomplish, but you're looking at either needing to just rename the routes or you may need to override the update method.

If it's just a route renaming issue, it should be something like this:

devise_for :users, :controllers => { registrations: 'registrations', sessions: 'sessions' }, :path => '', :path_names => {:sign_in => 'login', :sign_up => 'register'}

Of course update to whatever your names are...

Check out: https://github.com/plataformatec/devise/blob/master/app/controllers/devise/registrations_controller.rb#L41

Lines 41 - 62 is the update method on the registrations_controller and is what you're going to have to override to redirect to a certain action given whatever conditions you have. I haven't personally done it for this scenario so this is about as far as I can help for this one.


Login or Create An Account to join the conversation.

Subscribe to the newsletter

Join 27,623+ developers who get early access to new screencasts, articles, guides, updates, and more.

    By clicking this button, you agree to the GoRails Terms of Service and Privacy Policy.

    More of a social being? We're also on Twitter and YouTube.