Reputation: 31
I'm trying to use enum in my project. but I don't know how to use it with simple_form input collection. my code makes an error. this is my enum definition in user.rb:
enum role: [ :guest, :super_admin, :advertiser, :publisher, :account_manager]
and this is my view code:
<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= render 'devise/shared/error_messages', object: f.object %>
<div class="form-inputs">
<%= f.input :name, required: true, autofocus: true%>
<%= f.input :email, required: true %>
<%= f.input :password, required: true, placeholder: "min. 6 characters",
input_html: {"parsley-minlength" => 6, "error-container" =>"#errorBlock"} %>
<%= f.input :password_confirmation, required: true,
input_html: {"parsley-equalto" => "#user_password"} %>
**<%= f.input :role, collection: User.roles %>**
</div>
Upvotes: 3
Views: 6371
Reputation: 1
Add this line to your application's Gemfile:
gem 'enum_help'
And then execute:
$ bundle
In model
enum role: [ :guest, :super_admin, :advertiser, :publisher, :account_manager]
In _form.html.erb using simple_form:
<%= f.input :role %>
For more information: https://github.com/zmbacker/enum_help
Upvotes: -1
Reputation: 7070
When you do something like Resource.roles
it will return a hash of keys and values like
{"guest"=>0, "super_admin"=>1, ...}
However, if you're using the enum
in a form, by default it will simple display an integer field. Using simple_form
, you can specify a collection set for the enum
and it will return an array of the keys.
<%= f.input :role, collection: User.roles.keys %>
Since you pass in the collection:
option, it will automatically change the input field to a select. However, you can specify this manually as well with as: :select
or use check boxes.
Note that User.roles.keys
will return
["guest", "super_admin", ... ]
This should fix the error message that you were receiving. Before, it was displaying the enum name and the selection was setting the integer value of the enum. When setting a value for an enum attribute, you actually specify the key name, not the integer value.
This is from the documentation http://edgeapi.rubyonrails.org/classes/ActiveRecord/Enum.html#method-i-inherited
class Conversation < ActiveRecord::Base
enum status: [ :active, :archived ]
end
# conversation.update! status: 0
conversation.active!
conversation.active? # => true
conversation.status # => "active"
# conversation.update! status: 1
conversation.archived!
conversation.archived? # => true
conversation.status # => "archived"
# conversation.update! status: 1
conversation.status = "archived"
# conversation.update! status: nil
conversation.status = nil
conversation.status.nil? # => true
conversation.status # => nil
Note where they set the value of the status conversation.status = "archived"
, they set the key name of the enum and not the value 1. Hopefully this helps you.
Upvotes: 8
Reputation: 942
As I can see, User.roles will not return an array but will return a Hash like
{"guest"=>0, "super_admin"=>1, ...}
Also I don't know your migrations, but make sure you have the role field as integer in the database and not a string.
For more details on Rails enums refer the official manual and this awesome article on enums by thoughtbot
Upvotes: 0