Ruby/Rails - issues with JSON.parse/JSON.decode



我的控制器收到一个JSON字符串在参数中,看起来像这样:

{"serialized"=>"{"key":{"subkey1":"value","subkey2":"value"}"}

在我的控制器中,我尝试如下:

JSON.parse(params[:serialized], symbolize_names: true)

返回:

{:"key"=>{:subkey1=>"value", :subkey2=>"value"}

所有嵌套子键都用符号表示;键被以一种奇怪的方式符号化,所以它不响应哈希[key],而是响应哈希["key"]

如果我遍历Rails堆栈:

ActiveSupport::JSON.decode(params[:serialized]).symbolize_keys

我得到以下结果:

{:"key"=>{"subkey1"=>"value", "subkey2"=>"value"}

几乎与第一个相同,除了嵌套键;他们没有被象征。

我甚至尝试遍历哈希,试图手动标记键;没有成功:

Hash[params[:serialized]{ |k, v| [k.to_sym, v] }] # returns {:"key"=>{"subkey1"=>"value", "subkey2"=>"value2"}

为什么会发生这种情况?为什么键的符号是:"key"而不是:key?

乌利希期刊指南删除了最后一行(我怎么可能解决这个问题,因为我需要我的哈希来回答哈希[key]而不是哈希["key"].),所以这个问题看起来不那么实用,更理论化。

try on rails console.

require 'json'
string = {"serialized"=>"{"key":{"subkey1":"value","subkey2":"value"}"}
hash = JSON.parse string

我同意@boulder上面所说的。但是因为Hash[params[:serialized].symbolized_keys.map{ |k, v| [k.to_sym, v.symbolize_keys] }]是用来表示到一级的。我真的不会这么做的,永远不会。

这可能与你所要求的不同,但在Rails中访问哈希的键/值通常适合于hash.key而不是hash[:key]hash['key']
这是主要约定,也是访问@user.name等字段的原因。

Rails通过OpenStruct实现了这一点。要使用它,您可以这样做:

@foo = ActiveSupport::JSON.decode(params[:serialized]).symbolize_keys
obj = OpenStruct.new(@foo)
obj.key #=> {"subkey1"=>"value", "subkey2"=>"value"}

但是,再次,OpenStruct创建对象直到使用.key而不是':key'访问的一个级别。为了帮助实现这一点,我们有了Recursive OpenStruct,它完美地完成了这项工作。

我个人认为,在这种情况下,你应该在Rails中工作。

首先,:key和:"key"是表达完全相同事物的两种方式。事实上,如果你这样做:

> :key == :"key" 
=> true

所以给定一个散列,比如

h = {:"key" => "value"}
h[:key]
=> "value"

其次,如果您有嵌套的散列,您不仅希望手动标记键,还希望在值

中标记键。
Hash[params[:serialized].symbolized_keys.map{ |k, v| [k.to_sym, v.symbolize_keys] }]

当然,如果你有多个级别的"鸟巢",你需要更详细的东西

旧主题,但对于那些可能落在它上面的,Rails提供了方法deep_symbolize_keys,似乎正是op解析json后需要的:

hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } }
hash.deep_symbolize_keys
# => {:person=>{:name=>"Rob", :age=>"28"}}

来源:https://apidock.com/rails/Hash/deep_symbolize_keys

相关内容

最新更新