I have Projects model:
class Project < ApplicationRecord
acts_as_tenant :account
has_rich_text :description
validates :name, :progress, :priority, :status, presence: true
# Broadcast changes in realtime with Hotwire
after_create_commit -> { broadcast_prepend_later_to :projects, partial: "projects/index", locals: { project: self } }
after_update_commit -> { broadcast_replace_later_to self }
after_destroy_commit -> { broadcast_remove_to :projects, target: dom_id(self, :index) }
enum priority: { no_priority: 0, low: 1, medium: 2, high: 3 }
enum status: { not_started: 0, in_progress: 1, waiting: 2, done: 3 }
def priority
super.to_s.humanize
end
def status
super.to_s.humanize
end
end
On edit page I have this form:
<%= form_with model: @project do |form| %>
<div>
<%= form.label :name %>
<%= form.text_area :name %>
</div>
<div>
<%= form.label :priority %>
<%= form.select :priority, [["No priority", "no_priority"], ["Low", "low"], ["Medium", "medium"], ["High", "high"]], selected: form.object.priority %>
</div>
<div>
<%= form.submit %>
</div>
<% end %>
Problem is, when I want to edit existing project, dropdown select element don't select option from database, but only first one.
Generated HTML:
<select name="project[priority]" id="project_priority">
<option value="no_priority">No priority</option>
<option value="low">Low</option>
<option value="medium">Medium</option>
<option value="high">High</option>
</select>
What I need to do to have selected priority from database?
CodePudding user response:
I think you need to change your template slightly:
<div>
<%= form.label :priority %>
<%= form.select :priority, [["No priority", "No priority"], ["Low", "Low"], ["Medium", "Medium"], ["High", "High"]] %>
</div>
Why: Since priority
is overridden as super.to_s.humanize
, the value that the form helper gets is the humanized form rather than the enum key form.
If you want to get at the raw value for your enum, you can call the pluralized name of the enum as a method on the class, e.g. Project.priorities
. This will return the hash that the enum was defined as.
Further suggestion: I think that overriding the attribute methods from ActiveRecord is not worth the trouble it causes. The priority value is an attribute of the model (the data layer) while the humanized string really belongs on the view layer. I would suggest defining a new method called humanized_priority
on Project
to start off with, but you can take the separation of concerns further by extracting the method out into a view helper or using presenters.