首页 > 解决方案 > 混淆试图在 Ruby on Rails 中将字符串转换为 JSON 对象

问题描述

也许我一直没睡好。我认为这很简单,因为我无法将字符串转换为 JSON 对象。

在特定的控制器操作中,我正在执行以下操作:

def my_action
  user = User.find(current_user_id)
  profile = Profile.find_by(user_id: current_user_id)
  company = Company.find(id)
  colors = company.colors
  { id: user.id, username: user.username, email: user.email, profile: profile, company: company, colors: colors}
end

该变量colors来自我的 Postgres DB,位于数据类型为 JSON 的列中,并产生以下输出:

"{color0:[#2d2445,#433566,#5C4AB4,#685DF2,#6c6eff,#D6D3FB,#EAEAFF], color1: [#262474,#434595,#524FFF,#528fff,#71A3FF,#B0CCFF,#F1F6FF]}"

然后该输出在主 JSON 对象中返回,但它作为字符串提供。我正在尝试将该字符串转换为 JSON,以便它成为主对象内的一个对象。

我试过这样做,JSON.parse(colors)但出现解析错误:

JSON::ParserError: 767: unexpected token at '{color0:[#2d2445,#433566,#5C4AB4,#685DF2,#6c6eff,#D6D3FB,#EAEAFF], color1: [#262474,#434595,#524FFF,#528fff,#71A3FF,#B0CCFF,#F1F6FF]}'

关于如何将该字符串转换为可以在 JS 中使用的有效 JSON 对象的任何想法?

标签: javascriptruby-on-railsjson

解决方案


首先确保 db 中的数据是正确的。rails+postgres 中的 JSON/JSONB 列是开箱即用的(反)序列化的,company.colors.class应该已经是 Hash,但看起来在保存之前的某个时候它被转换为字符串(也是有效的 json 类型,因此没有保存时出错)。

在遗留项目中,这可能是因为从文本切换到 json 期间的双重序列化,如果仍然存在serialize :colors并且列已经是 json。或者在更早的某个时间点,可能是它在客户端被错误地序列化(json 是无效的命中)

作为恢复现有半无效数据的技巧,您可以:

if company.colors.is_a?(String)
  company.colors = JSON.parse(
    company.colors.gsub(/(#[0-9a-fA-F]+)/, '"\1"').gsub(/\b(\w+):/, '"\1":')
  )
end

推荐阅读