ruby-on-railsruby-on-rails-4deviseenumsrailsapps

Select enum from form to set role


Ruby on Rails 4.1

I am using Devise with enum role. It currently sets a defualt role when the User is created. I want to add a field to the form that creates Users to set the enum role.

I read this but it doesn't say how to utilize the new roles.

This is the User class

devise :database_authenticatable, :registerable, :confirmable,
     :recoverable, :rememberable, :trackable, :validatable
enum role: [:user, :vip, :admin, :developer, :marketing, :support, :translator]
after_initialize :set_default_role, :if => :new_record?

def set_default_role
  self.role ||= :user
end

This is the part of the form where I am trying to have a select to pick an enum role:

<div class="form-group">
  <%= f.collection_select :role, User.roles, :id, :enum, {prompt: "Select a role"}, {class: "form-control input-lg"} %>
</div>

The error:

NoMethodError - undefined method `enum' for ["user", 0]:Array:
actionview (4.1.1) lib/action_view/helpers/form_options_helper.rb:761:in `value_for_collection'

I have never used enum before and the documentation is not proving helpful. How do I make the enum options show?


Solution

  • To start, enum is not the name of an attribute. The name of the attribute is role.

    Take a look at the rails-devise-pundit example application, specifically the file app/views/users/_user.html.erb which is a partial that creates a form to allow the administrator to change a user's role. I doubt you want to use a collection_select for helper (that is suitable if you have a separate Role model). Instead, an ordinary select form helper will work.

    Here's a simple example that hardcodes the role options:

    <%= f.select(:role, [['User', 'user'], ['Vip', 'vip'], ['Admin', 'admin']]) %>
    

    Here is a better example that avoids hardcoding the roles in the form:

    <%= f.select(:role, User.roles.keys.map {|role| [role.titleize,role]}) %>
    

    The statement obtains an array of roles from the User model and constructs an array of key-value pairs using the map method.