Reputation: 179
I declare a model with an enum
type like:
class Event < ActiveRecord::Base
enum event_type: { "special_event" => 0,
"pto" => 1,
"hospitality" => 2,
"classroom" => 3
}
Then in my update view, I have a form with:
<%= simple_form_for @event do |f| %>
<%= f.input :event_type, collection: Event.event_types.keys %>
...
<% end %>
This works great, and I get a select populated with my enumerated types.
When I perform the @event.update(event_params)
in my controller, I can check the db and see that the event_type
field has been updated to the correct integer value.
However, when I revisit the edit page, the select shows a nil value. If I check its value by adding a debug line to my form:
<%= f.input :event_type, collection: Event.event_types.keys %>
<%= debug @event %>
I see that the value for event_type
is correct:
--- !ruby/object:Event
attributes:
...
event_type: '2'
but the input selector is still blank rather than showing "hospitality" as it should.
Any ideas would be greatly appreciated. :)
Upvotes: 18
Views: 16782
Reputation: 1
<%= f.input :event_type, collection: Event.event_types.transform_keys(&:titleize) %>
Just passing the enum hash as it is would be enough. but if you want to alter the options you can use transform_keys
Upvotes: 0
Reputation: 8418
For example, assuming you have an enum like this one in your model (Model Role in the example):
enum :work_type, in_person: "in_person", remote: "remote", hybrid: "hybrid"
This will work in your view
= f.input :work_type, as: :select, collection: Role.work_types.collect { |key, value| [key.to_s.titleize, value] }
This will out put the following HTML:
<select class="form__input" name="role[work_type]" id="role_work_type">
<option selected="selected" value="in_person">In Person</option>
<option value="remote">Remote</option>
<option value="hybrid">Hybrid</option>
</select>
Upvotes: 2
Reputation: 148
I got stuck on this one too. I needed to titlieze my enums so they wouldn't look so wonky with the snake_case that I was using. I used to_a to take the ruby hash and turn it into an array and then I used collect to return a new array in the format that I needed.
collection: Event.event_type.to_a.collect{|c| [c[0].titleize, c[0]]}
Hopefully this will help someone else out.
Upvotes: 8
Reputation: 1402
Vincent's solution gives me the error: '0' is not a valid 'fieldname'
I had to add keys
as suggested in other stackoverflow post:
<%= f.input :event_type, collection: Event.event_types.keys %>
Upvotes: 13
Reputation: 443
this line worked just fine. <%= f.input :event_type, collection: Event.event_types %>
Do you have to manually set the selected value ? what's your version of simple_form ?
Upvotes: 27
Reputation: 1125
I'm using draper as decorator, so I'd like to add words translation into model's decorator. Here is my code:
app/decorators/meter_decorator.rb
class MeterDecorator < Draper::Decorator
delegate_all
STATUS_MAPPING = {
uninitialized: '未安装',
good: '良好',
broken: '故障',
disabled: '禁止'
}
def status
STATUS_MAPPING[object.status.to_sym]
end
end
views/meters/_form.html.erb
<%= f.input :status, collection: MeterDecorator::STATUS_MAPPING, label_method: :last, value_method: :first, include_blank: false %>
views/meters/index.html.erb
<td><%= meter.decorate.status %></td>
Upvotes: 0
Reputation: 2092
Use the enum_help gem. Lets you do this:
<%= f.input :event_type %>
Upvotes: 8
Reputation: 179
Thanks for following this up. I believe the issue I reported was caused by an incorrect declaration for event_type. In my migration, I had accidentally defined event_type as String rather than an Integer:
class CreateEvents < ActiveRecord::Migration
def change
create_table :events do |t|
...
t.string :event_type
...
end
end
end
I believe that enum's should be declared as integers to work correctly. Unfortunately, I did not test that changing the type to integer makes it work because I actually ended up using a different approach. Rather than using an enum I instead defined my collection of event types in my model:
class Event < ActiveRecord::Base
def self.types
['Special_Events', "On-Going", 'PTO', "Classroom"]
end
...
end
And, then in my form, used simple form with this syntax:
<%= f.input :event_type, collection: Event.types, input_html: { autocomplete: 'off' } %>
And all worked well.
Upvotes: 0
Reputation: 179
With some more research, I came up with the following solution:
<%= f.input :event_type, collection: Event.event_types.keys,
:selected => Event.event_types.keys[@event[:event_type].to_i],
input_html: { autocomplete: 'off' } %>
So, I had to do 2 things:
Alternate, simpler solutions would be welcomed!
Upvotes: -1