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

Rails7+MySQL8下JSON字段转Ruby Hash报错问题求助

解决Rails 7中JSON字段返回嵌套Hash及JSON.parse报错问题

问题核心

你执行author.address得到的已经是Ruby Hash对象,不是JSON字符串,所以调用JSON.parse(author.address)会触发类型错误——JSON.parse仅接受字符串参数,传入Hash自然会报错。

为什么会出现嵌套Hash结构?

你在迁移中把address设为:json类型,Rails默认会自动将数据库中的JSON数据转换为Ruby Hash。但当前返回{"address"=>{"city"=>"San Francisco", ...}}的嵌套结构,大概率是存储数据时错误地给目标Hash多套了一层address键,比如存储时写了:

author.update(address: { address: { city: "San Francisco", ... } })

而非正确的直接传入目标Hash:

author.update(address: { city: "San Francisco", ... })

解决步骤

  1. 验证原始数据
    直接查询数据库确认address字段的原始值:

    Author.connection.execute("SELECT address FROM authors WHERE id = #{author.id}").first
    

    如果返回的JSON确实包含嵌套的address键,说明存储逻辑和数据都需要修正。

  2. 批量修正现有数据
    遍历所有作者记录,把嵌套的address值提取出来覆盖原字段:

    Author.find_each do |a|
      next unless a.address.is_a?(Hash) && a.address.key?('address')
      a.update_column(:address, a.address['address']) # 使用update_column跳过回调,提升效率
    end
    
  3. 规范后续存储逻辑
    以后存储address时,直接传入目标Hash即可:

    author.update(address: { city: "San Francisco", state: "CA", street: "One Main St", postal_code: "94016" })
    

    此时author.address会直接返回{"city"=>"San Francisco", ...}的Hash,无需额外转换。

  4. 特殊场景兼容(可选)
    如果后续遇到address可能是字符串的情况,可以增加类型判断:

    parsed_address = if author.address.is_a?(String)
                       JSON.parse(author.address)
                     else
                       author.address
                     end
    

内容的提问来源于stack exchange,提问作者EastsideDev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 14:10:28