1

First-time poster, many-time finder-of-answers on the site (thank you!). I'm using Rails 5.2.3, ruby-2.6.2 and Devise gem 4.6.2. I have not been able to get an answer to work, even though there are plenty somewhat related questions here, here, here and here.

When a new User signs up, I want them to select their Company from a dropdown list (already created) in the sign-up form. (Eventually, this will be an admin role, but that's beyond the scope of this question.)

I created a registrations controller and added code per a number of the previous posts. Update, I was not extending Devise as I should have as indicated here: Extending Devise Registration Controller. This is my new Registrations controller.

class Users::RegistrationsController < Devise::RegistrationsController
  before_action :configure_sign_up_params, only: [:create]
  before_action :configure_account_update_params, only: [:update]


  def new
     @companies = Company.all
     super

  end

  def create
    @companies = Company.all
    super
  end

  protected


  def configure_sign_up_params
     devise_parameter_sanitizer.permit(:sign_up, keys: [:company_id])
  end


  def configure_account_update_params
     devise_parameter_sanitizer.permit(:account_update, keys: [:company_id])
  end

end

And created new files in views/registrations with new.html.erb and edit.html.erb that I copied the exact code from the devise/registrations views.

I updated my routes.rb file to include:

devise_for :users, :controllers => { registrations: 'users/registrations', sessions: 'users/sessions' }

My User model is:

class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
  belongs_to :company
  accepts_nested_attributes_for :company
end

My Company model is:

class Company < ApplicationRecord
    has_many :users
end

In the new user registration form, this works to provide the dropdown, but when I try to create the new user, it says: 1 error prohibited this user from being saved: Company must exist.

    <%= f.collection_select :company, @companies, :id, :name, prompt: true %>

I thought this post would have the answer, but that appears to use Rails 3 and attr_accessible, which was deprecated in Rails 4.

I don't really understand what accept_nested_attributes_for :company does. The only thing in the Company model is the name.

Thank you in advance!

Trisha
  • 11
  • 5

2 Answers2

1

Welcome to StackOverflow.

In order to add more parameters to devise's sign up form, you'll need to sanitize the corresponding parameters using devise's sanitizer.

You should do that like this:

class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:company_id])
  end
end

You can find more information about parameter sanitizing and adding custom fields in this section of devise's readme

If you also want to add a select field including all the existing companies, you should add a collection select:

<%= f.collection_select :company_id, Company.all, :id, :name %>

Waclock
  • 1,686
  • 19
  • 37
  • Thank you - I tried that, but I couldn't make it work unless the user can input the integer value of the company_id. I want to have them select the name of the company from a dropdown. – Trisha Jul 05 '19 at 14:23
  • That's kind of a different problem though, you'd have 2 options: 1. Show a select with existing companies, where the user can pick his own company. 2. Pre-process the company, and then manually the company_id to the params – Waclock Jul 05 '19 at 15:26
  • Oh no, I must not have explained it well. I'm trying to get Option 1 – Trisha Jul 05 '19 at 17:35
  • That's a very simple solution, so I created a new project to try it (my code currently has a lot more in it that might mess with this solution). I basically installed Devise, scaffold'd Company and then implemented your solution. There's an error: NoMethodError in Devise::Registrations#new. undefined method `company_id' for # – Trisha Jul 08 '19 at 19:26
  • Well, you have to add a `company_id` to your user model in order for it to work, did you add a custom migration for it, or add it in the devise migration? – Waclock Jul 08 '19 at 19:27
  • Custom migration. rails g migration AddCompanyToUser company_id:integer – Trisha Jul 08 '19 at 21:45
  • @Trisha Don't use integer - https://stackoverflow.com/questions/7861971/generate-model-using-userreferences-vs-user-idinteger – James Brown Jul 10 '19 at 00:35
  • Great hack! Thanks! – Trisha Jul 11 '19 at 13:43
0

Got it!

To extend the Devise controller, follow the help here: Extending Devise Registration Controller

The User models must also be updated to include the optional: true because here https://blog.bigbinary.com/2016/02/15/rails-5-makes-belong-to-association-required-by-default.html:

class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
  belongs_to :company, optional: true
  accepts_nested_attributes_for :company
end
Trisha
  • 11
  • 5