Rails数组多选框存储为字符串,如何在编辑时回显选中值
看起来你已经搞定了多选功能和数据存储,就差编辑个人资料时回显选中的语言选项了,我来帮你一步步解决这个问题:
1. 让模型自动处理字符串和数组的转换
数据库里存的是JSON格式的字符串,我们需要让模型在读取字段时自动把它转成数组,保存时再把数组转成干净的JSON字符串(还能顺便过滤掉你示例里的空字符串)。假设你的模型是User,打开app/models/user.rb添加以下代码:
def spoken_languages # 读取数据库值,解析成数组;如果是空值就返回空数组 value = super value.present? ? JSON.parse(value) : [] end def spoken_languages=(values) # 过滤掉空选项,再转成JSON字符串存储 filtered_values = values.reject(&:blank?) super(JSON.generate(filtered_values)) end
这样以后,你调用@user.spoken_languages得到的就是一个标准数组,比如["0", "1", "2"],而不是数据库里的"[\"\", \"0\", \"1\", \"2\"]"这种字符串。
2. 修正表单的多选框代码
你当前的select代码里,@spoken_languages_datas.each { |p| [p] }是多余的——因为@spoken_languages_datas已经是[["显示文本", 选项值], ...]的正确格式了,直接用它就行。而且Rails的表单助手会自动识别模型返回的数组,把对应的选项设为选中状态。
修改后的表单代码:
.row .col-6 = form.label :spoken_languages, @spoken_languages_title = form.select(:spoken_languages, @spoken_languages_datas, {prompt: 'Select a language'}, {multiple: true, size: @spoken_languages_datas.count, style: 'height: 125px;'})
如果遇到自动选中不生效的情况,也可以手动指定selected参数兜底:
= form.select(:spoken_languages, @spoken_languages_datas, {prompt: 'Select a language', selected: @user.spoken_languages}, {multiple: true, size: @spoken_languages_datas.count, style: 'height: 125px;'})
3. 确保控制器允许数组参数
最后,要让控制器能正确接收多选框提交的数组值。打开app/controllers/users_controller.rb,在user_params方法里把spoken_languages设为数组类型:
def user_params params.require(:user).permit( # 这里放你其他允许的字段,比如:name, :email... spoken_languages: [] ) end
验证效果
现在你打开编辑页面,应该能看到之前选中的语言已经被自动勾选了。而且新提交的多选值会被过滤掉空选项,以整洁的JSON数组形式存在数据库里(比如原来的["", "0", "1"]会变成["0", "1"])。
内容的提问来源于stack exchange,提问作者eth3rnit3

