如何使用ActiveAdmin、Ruby on Rails与MySQL将多表单字段存入单个JSON列
解决方案
问题原因
你当前的写法有两个核心问题:
- 表单代码存在语法错误,
f.inputs后的逗号、for: => :fees_list的混合语法都是无效写法 - Formtastic的
for:配置默认用于处理ActiveRecord关联对象,无法直接作用于JSON类型字段,因此不会渲染对应的输入框
不需要额外安装Gem就能实现你的需求,Rails + Formtastic原生支持JSON字段的读写操作。
修复步骤
1. 模型层添加JSON字段访问器
在app/models/price.rb中添加store_accessor声明,将JSON字段内的键映射为模型的普通属性:
class Price < ApplicationRecord # 将fees_list内的键注册为模型可直接访问的属性 store_accessor :fees_list, :fee_1, :fee_2 # 可选:添加数值类型校验 validates :fee_1, :fee_2, numericality: { allow_nil: true } end
2. 修正表单代码
不需要嵌套for块,直接将fee_1、fee_2作为普通表单字段声明即可:
<%= f.input :fee_1, required: false %> <%= f.input :fee_2, required: false %>
如果你需要手动指定值,可以使用&.dig避免fees_list为nil时报错:
<%= f.input :fee_1, required: false, input_html: { value: resource.fees_list&.dig('fee_1') } %> <%= f.input :fee_2, required: false, input_html: { value: resource.fees_list&.dig('fee_2') } %>
3. 配置Strong Parameters
在ActiveAdmin的Price管理文件app/admin/price.rb中,将fee字段添加到允许的参数列表:
ActiveAdmin.register Price do # 原有其他配置 permit_params :你原有的其他参数字段, :fee_1, :fee_2 end
动态键值对场景适配
如果你需要动态添加不限数量的fee项,可以直接通过指定表单input的name属性实现,不需要提前在模型注册store_accessor:
<%= f.input :fee_1, required: false, input_html: { name: 'price[fees_list][fee_1]', value: resource.fees_list&.dig('fee_1') } %>
对应Strong Parameters配置改为允许接收整个fees_list哈希:
permit_params :你原有的其他参数字段, fees_list: {}
内容的提问来源于stack exchange,提问作者Fede Arg
相关产品推荐
相关产品推荐

