You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails中如何根据Task的typeOf枚举值动态展示status_is下拉选项

实现方案

现有代码未对任务类型和状态的可选关联做限制,直接输出所有状态枚举值作为下拉选项,按以下步骤修改即可实现需求:

第一步:调整Model层逻辑

修正枚举值的大小写问题,新增状态选项获取方法:

class Task
  enum typeOf: %i[feature bug]
  # 统一枚举值为小写,修正原大写New的问题
  enum status_is: %i[new started completed resolved]

  # 根据任务类型返回对应的可选状态列表
  def self.status_options_for(type)
    base_statuses = %w[new started]
    type == 'feature' ? base_statuses + ['completed'] : base_statuses + ['resolved']
  end
end

第二步:修改视图表单代码

给两个下拉框添加id方便JS获取,默认按feature类型加载状态选项,表单字段提示同步翻译为中文:

<%= form_for :task, url: project_tasks_path, :html => {:multipart => true, :class => "task-form"} do |f| %>
  <%= f.hidden_field :project %>
  标题: <%=f.text_field :title, class:"form-control" %><br>
  描述: <%=f.text_field :description, class:"form-control" %><br>
  <label for="deadline">截止时间</label><input type="datetime-local" id="deadline" name="deadline" ><br>
  截图: <%=f.file_field :screen_shot, multiple: true, class:"form-control" %>
  <div class="field">
    <%= f.label :typeOf, class:"form-control" %><br />
    <%= f.select(:typeOf, Task.typeOfs.keys.map {|role| [role.titleize,role]}, {}, {id: 'task-type'}) %>
  </div>

  <div class="field">
    <%= f.label :status_is, class:"form-control" %><br />
    <%= f.select(:status_is, Task.status_options_for('feature').map {|s| [s.titleize, s]}, {}, {id: 'task-status'}) %>
  </div>
  <%= f.submit "新增" %>
<% end %>

第三步:添加前端联动逻辑

在视图文件末尾添加以下JS代码,实现任务类型切换时状态选项自动更新:

<script>
document.getElementById('task-type').addEventListener('change', function() {
  const selectedType = this.value;
  const statusSelect = document.getElementById('task-status');
  const baseOptions = [
    { value: 'new', text: 'New' },
    { value: 'started', text: 'Started' }
  ];
  const finalOptions = selectedType === 'feature' 
    ? [...baseOptions, { value: 'completed', text: 'Completed' }]
    : [...baseOptions, { value: 'resolved', text: 'Resolved' }];
  
  statusSelect.innerHTML = '';
  finalOptions.forEach(option => {
    const opt = document.createElement('option');
    opt.value = option.value;
    opt.textContent = option.text;
    statusSelect.appendChild(opt);
  });
});
</script>

第四步:新增后端校验(推荐添加)

在Task类中新增校验规则,防止前端篡改数据提交非法状态:

class Task
  # ...原有代码不变
  validate :status_matches_type

  private
  def status_matches_type
    return unless typeOf.present? && status_is.present?
    allowed_statuses = Task.status_options_for(typeOf)
    errors.add(:status_is, "所选状态不符合当前任务类型") unless allowed_statuses.include?(status_is)
  end
end

内容的提问来源于stack exchange,提问作者waqar ahmad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 22:06:04