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?
Here is how I did it, with internationalization and ordering, and auto select the current_user role if already defined. It assumes that you have a locale file with a roles: category containing all your enum roles such as :
The cleanest way that I've come with in order to use
collection_select
withenum
s is the following:To start,
enum
is not the name of an attribute. The name of the attribute isrole
.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 ordinaryselect
form helper will work.Here's a simple example that hardcodes the role options:
Here is a better example that avoids hardcoding the roles in the form:
The statement obtains an array of roles from the User model and constructs an array of key-value pairs using the
map
method.As enum is a wrapper for integer in Rails, and I wanted to store strings in DB instead, I did the following:
In my form,
As I was using PostGREsql server wherein a pre-defined datatype can be declared, I appended a column called 'year' to the Child model of type'year'.
and changed the migration file as below.
Finally,
rails db:migrate
for DB migration changes.So, now rails enum can be used to store strings in DB.
Since you are using Rails 4 or higher, enums are even less complicated.
Given the following enum:
Enums expect the HTML option attribute
value
to be the enum key:Knowing this, you can pass in the enum keys.
Then using CSS you can modify the appearance.