У меня есть модель проектов:
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
На странице редактирования у меня есть эта форма:
<%= 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 %>
Проблема в том, что когда я хочу отредактировать существующий проект, элемент выбора раскрывающегося списка не выбирает вариант из базы данных, а только первый.
Сгенерированный 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>
Что мне нужно сделать, чтобы выбрать приоритет из базы данных?
@BenFenner это не помогло. Думаю проблема на стороне просмотра, но для меня это странно.
Я думаю, вам нужно немного изменить свой шаблон:
<div>
<%= form.label :priority %>
<%= form.select :priority, [["No priority", "No priority"], ["Low", "Low"], ["Medium", "Medium"], ["High", "High"]] %>
</div>
Почему: поскольку priority
переопределяется как super.to_s.humanize
, значение, которое получает помощник формы, является гуманизированной формой, а не формой ключа перечисления.
Если вы хотите получить необработанное значение для вашего перечисления, вы можете вызвать имя перечисления во множественном числе как метод класса, например. Project.priorities
. Это вернет хэш, в котором было определено перечисление.
Дальнейшее предложение: Я думаю, что переопределение методов атрибутов из ActiveRecord не стоит проблем, которые оно вызывает. Значение приоритета является атрибутом модели (уровня данных), в то время как гуманизированная строка действительно принадлежит уровню представления. Я бы предложил для начала определить новый метод с именем humanized_priority
на Project
, но вы можете еще больше разделить задачи, извлекая метод в помощник представления или используя ведущие.
У меня есть две идеи. Во-первых, вы отправляете правильное значение атрибуту
selected:
? Вы уверены, чтоform.object.priority
имеет ожидаемое значение? Что произойдет, если вместо этого вы попробуете@project.priority
? Второй идеей было бы использоватьform_for
и его хелперы, что действительно является правильным, IMO, что позволит использовать хелперoptions_for_select
, который принимает выбранное значение в качестве второго аргумента, который будет выглядеть так:form.select(:priority, options_for_select([["No Priority", "no_priority"], ["Low", "low"], ["Medium", "medium"], ["High", "high"]], @project.priority)