Search code examples
ruby-on-railsrubyenumsdevise

Ruby on rails user role always remains nil using enum


I am trying to add multiple user role functionality in devise. I am using enum for different roles, but somehow user role always remains nil after a new user signs up.

here is my implementation

user model

  class User < ApplicationRecord
      rolify
  
      devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

      enum role: { student: 0, assistant: 1, teacher: 2}

end

I also added role in strong params of registration controller

registration_controller

class RegistrationsController < Devise::RegistrationsController

    private
  
    def sign_up_params
      params.require(:user).permit(:username, :email, :password, :password_confirmation, keys: [:role])
    end
  
    def account_update_params
      params.require(:user).permit(:username, :email, :password, :password_confirmation, :current_password, keys: [:role])
    end
  
  end

view

        <%= f.select :role, User.roles %>

What I want is that role of new user should be whatever he/she selects from dropdown while registering But its role is always set to nil after registering. Can someone please explain how to fix this

I have read many answers and added key: [:role] in strong params but still its not working

Thanks


Solution

  • If you intend on using Rolify you should remove that enum column.

    class User < ApplicationRecord
      rolify
      devise :database_authenticatable, :registerable,
             :recoverable, :rememberable, :validatable
    end
    

    Rolify uses two tables (roles and users_roles) to store the roles of a user. This allows a user to have many roles while a role can have many users.

    While you can create your own primitive role system based on an enum column having both in tandem will certainly confusion as Rolify's methods such as .has_role? will not take your enum column into account.

    If you want to let users select roles with rolify you would do:

    <%= f.collection_select :role_ids, 
        Role.where(name: ['student', 'assistant', 'teacher']), :id, :name %>
    
    class RegistrationsController < Devise::RegistrationsController
    
        private
      
        def sign_up_params
          params.require(:user).permit(:username, :email, :password, :password_confirmation, role_ids: [])
        end
      
        def account_update_params
          params.require(:user).permit(:username, :email, :password, :password_confirmation, :current_password, role_ids: [])
        end
    end