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

如何使用ActiveAdmin、Ruby on Rails与MySQL将多表单字段存入单个JSON列

解决方案

问题原因

你当前的写法有两个核心问题:

  1. 表单代码存在语法错误,f.inputs后的逗号、for: => :fees_list的混合语法都是无效写法
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 20:15:03