I am using the enums in Rails 4.1 to keep track of colors of wine.
Wine.rb
class Wine < ActiveRecord::Base
enum color: [:red,
Alright, so apparently, you shouldn't send the integer value of the enum to be saved. You should send the text value of the enum.
I changed the input to be the following:
f.input :color, :as => :select, :collection => Wine.colors.keys.to_a
Which generated the following HTML:
<select id="wine_color" name="wine[color]">
<option value=""></option>
<option value="red">red</option>
<option value="white">white</option>
<option value="sparkling">sparkling</option>
</select>
Values went from "0" to "red" and now we're all set.
If you're using a regular ol' rails text_field it's:
f.select :color, Wine.colors.keys.to_a
If you want to have clean human-readable attributes you can also do:
f.select :color, Wine.colors.keys.map { |w| [w.humanize, w] }
If you use enum in Rails 4 then just call Model.enums
:
f.select :color, Wine.colors.keys
To create HTML:
<select name="f[color]" id="f_color">
<option value="red">red</option>
<option value="white">white</option>
<option value="sparkling"> sparkling </option>
</select>
Or add method in controller:
def update_or_create
change_enum_to_i
....
end
def change_enum_to_i
params[:f]["color"] = params[:f]["color"].to_i
end
Here is what worked for me, Rails 4+:
class Contract < ApplicationRecord
enum status: { active: "active",
ended: "active",
on_hold: "on_hold",
terminated: "terminated",
under_review: "under_review" ,
unknown: "unknown"
}
end
in my _form.html.erb
, I have this:
<div class="field">
<%= form.select :status, Contract.statuses.keys, {}%>
</div>
test from Console after adding a record:
2.3.0 :001 > Contract.last.status
Contract Load (0.2ms) SELECT "contracts".* FROM "contracts" ORDER BY "contracts"."id" DESC LIMIT ? [["LIMIT", 1]]
=> "active"
Here's my solution (my roles have underscores in them like "sales_rep"), and for some reason this was how I needed to get a blank option to work (with simpleform?):
In ApplicationHelper:
def enum_collection_for_select(attribute, include_blank = true)
x = attribute.map { |r| [r[0].titleize, r[0]] }
x.insert(0,['', '']) if include_blank == true
x
end
Then in my form:
<%= f.input :role, collection: enum_collection_for_select(User.roles), selected: @user.role %>
No need converting the enum hash to array with to_a
. This suffice:
f.select :color, Wine.colors.map { |key, value| [key.humanize, key] }
If you need to handle the i18n based on the enum keys you can use:
<%= f.select :color, Wine.colors.keys.map {|key| [t("wine.#{key}"), key]} %>
and in the tranlations you can set the colors:
wine:
red: Red
white: White