Ruby中如何将带=>分隔符的Ransack参数字符串转换为Hash?
问题根因
你遇到的JSON::ParserError报错是因为待转换的字符串是Ruby原生Hash的字面量格式,并非标准JSON格式(JSON规范要求键值分隔符为冒号:而非=>),因此JSON.parse无法直接识别解析。
可行解决方案
- 方案1:使用
eval直接解析(仅适用于参数来源完全可信的场景)
直接通过Ruby内置的eval方法执行Hash字面量字符串,得到标准Hash对象:
param_str = "{\"processed_at_gteq_datetime\"=>\"2021-08-01\", \"processed_at_lteq_datetime\"=>\"2021-09-14\", \"status_eq\"=>\"processed\"}" ransack_params = eval(param_str) # 输出结果:{"processed_at_gteq_datetime"=>"2021-08-01", "processed_at_lteq_datetime"=>"2021-09-14", "status_eq"=>"processed"}
注意:eval会执行字符串内的任意Ruby代码,若参数存在用户可控的可能性,请勿使用该方案,避免代码注入风险。
- 方案2:格式替换后用
JSON.parse解析(通用安全方案)
先将字符串内的Hash分隔符=>替换为JSON标准的冒号:,再执行JSON解析,全程不会执行额外代码,安全性更高:
param_str = "{\"processed_at_gteq_datetime\"=>\"2021-08-01\", \"processed_at_lteq_datetime\"=>\"2021-09-14\", \"status_eq\"=>\"processed\"}" # 替换分隔符后解析 ransack_params = JSON.parse(param_str.gsub('=>', ':')) # 输出结果:{"processed_at_gteq_datetime"=>"2021-08-01", "processed_at_lteq_datetime"=>"2021-09-14", "status_eq"=>"processed"}
如果参数值中可能存在=>字符,可使用更精准的正则替换避免误改:param_str.gsub(/(")\s*=>\s*(")/, '\1: \2')。
- 方案3:传递前提前序列化(最优实践,从根源避免转换问题)
在页面间传递参数前,先将原始Hash转为标准JSON字符串再传递,接收端直接用JSON.parse解析即可,无需额外格式处理:
# 传递侧代码 original_hash = {"processed_at_gteq_datetime"=>"2021-08-01", "processed_at_lteq_datetime"=>"2021-09-14", "status_eq"=>"processed"} transfer_str = original_hash.to_json # 得到的transfer_str为标准JSON格式,可直接传递:{"processed_at_gteq_datetime":"2021-08-01","processed_at_lteq_datetime":"2021-09-14","status_eq":"processed"} # 接收侧代码 ransack_params = JSON.parse(transfer_str)
内容的提问来源于stack exchange,提问作者SsPay
相关产品推荐
相关产品推荐

