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
相关产品推荐
相关产品推荐

