如何在Rails Scaffold中创建可保存状态的复选框?
最简单的Rails非生产环境复选框实现方案(合同管理场景)
嘿,我来给你整个最省心的非生产环境方案——不用搞复杂的多表关联,直接用字符串存勾选的标签,快速搞定你遇到的复选框存值问题:
步骤1:给合同表添加存储标签的字段
如果你的Contract模型已经存在,直接生成迁移添加tags字符串字段:
rails generate migration AddTagsToContracts tags:string rails db:migrate
(如果是刚生成scaffold,直接在scaffold命令里加tags:string就行,比如rails generate scaffold Contract name:string tags:string)
步骤2:修改模型,处理数组和字符串的转换
因为复选框提交的是数组,但我们用字符串存,所以在app/models/contract.rb里加两个方法,自动转格式:
class Contract < ApplicationRecord # 把提交的数组转成逗号分隔的字符串存库 def tags=(values) super(values.reject(&:blank?).join(',')) end # 取数据时转成数组,方便视图判断勾选状态 def tags super.to_s.split(',') end end
步骤3:放行强参数(这是你之前存不进去的核心原因)
Rails默认会拦截未授权的参数,所以在app/controllers/contracts_controller.rb的强参数方法里,一定要加上tags: []:
private def contract_params params.require(:contract).permit(:你的其他字段, tags: []) end
步骤4:修改表单视图,添加复选框
打开app/views/contracts/_form.html.erb,添加你要的复选框组,用Rails的check_box_tag更省心:
<div class="field"> <%= label_tag :contract_tags, '选择标签:' %> <br> <%= check_box_tag 'contract[tags][]', 'Toll', @contract.tags.include?('Toll') %> <%= label_tag nil, '□ Toll' %> <br> <%= check_box_tag 'contract[tags][]', 'Chemist', @contract.tags.include?('Chemist') %> <%= label_tag nil, '□ Chemist' %> </div>
这里的contract[tags][]会把勾选的值以数组形式提交,模型里的方法会自动转成字符串存到数据库。
步骤5:(可选)在详情页显示勾选的标签
如果要在合同详情页展示已选标签,在app/views/contracts/show.html.erb里加:
<p> <strong>已选标签:</strong> <%= @contract.tags.join(', ') %> </p>
这样操作完,你勾选复选框提交后,数据就能正常存到数据库,编辑页面也会自动保留之前的勾选状态,完全满足非生产环境的测试需求~
内容的提问来源于stack exchange,提问作者Gabriel Savian
相关产品推荐
相关产品推荐

