2014-01-09 52 views
6

问题摘要:我试图使用Oj gem将哈希序列化为JSON。看来Oj不会自动将哈希的符号键转换为字符串。我想知道如果Oj有序列化期间“串化”的选项?使用Oj.dump序列化时将符号转换为字符串

这是我的散列的例子:

example_hash = 
{:id=>1234, 
    :asset_number=>"1234-5678", 
    :latitude=>34.78495, 
    :longitude=>-92.12899, 
    :last_tracking_record_id=>123456789, 
    :bearing=>42, 
    :threat_level=>:severe} 

和上面呈现,像这样:

render json: Oj.dump(example_hash) 

产生的JSON不幸的是有一个看起来就像上面的键,这意味着我会需要像这样访问JavaScript中的元素:response[:asset_number]。由于客户端代码是在几个月前实现的,并且现在只添加了Oj,所以我希望找到一种在序列化服务器端对字符串化的方法。

Oj有一个选项叫做symbol_keys,它是一个布尔值,但是将其设置为truefalse在这方面似乎没有效果。

我迄今发现的唯一解决方案是使用with_indifferent_access,this answer中的建议,但是在某些情况下,我有散列数组;虽然我可以在技术上为该数组中的每个散列调用该方法,但鉴于Oj旨在加快Json序列化的速度,我宁愿找到一种方法来使用Oj本身执行此操作。最终,我想知道Oj中是否有一个选项或设置将在系列化期间执行此

回答

9

在我写这个问题时,我找到了答案。由于我在StackOverflow上找不到与此问题有关的任何其他答案(特别是关于Oj gem),所以我会保留这篇文章,希望能够帮助其他人解决我的问题。

根据this previously discussed issue on GitHub,将选项mode设置为:compat确实会将符号转换为字符串。所以,我的渲染行现在看起来是这样的:

render json: Oj.dump(example_hash, mode: :compat) 

按照Oj documentation for default_options:compat模式的定义如下:

...与其他系统兼容。它会序列化任何对象,但会检查Object是否实现to_hash()或to_json()方法。 如果存在该方法用于序列化对象。 to_hash()更灵活,并且产生更一致的输出,所以它 优先于to_json()方法。如果to_json() 或to_hash()方法都不存在,则使用Oj内部对象变量 编码。

所以,如果我正确地解释说,看来这个解决方案的工作,因为它是最终使用Hash类的to_json方法。

我不确定自己是否影响了性能(正面或负面),但至少它使我无需在数组情况下手动调用with_indifferent_accessto_json

更新

在性能有关,cmwright做了一些基准测试,并与这些结果出来了:

Rehearsal ---------------------------------------------- 
json  13.990000 0.250000 14.240000 (14.257051) 
oj default 3.260000 0.230000 3.490000 ( 3.491028) 
oj compat 3.360000 0.240000 3.600000 ( 3.593109) 
------------------------------------ total: 21.330000sec 

       user  system  total  real 
json  13.740000 0.240000 13.980000 (13.992641) 
oj default 3.020000 0.230000 3.250000 ( 3.248077) 
oj compat 3.060000 0.230000 3.290000 ( 3.286443) 

好像compat选项至少在与默认Oj选项面值,并且比普通的ol to_json更有效。

这是包含基准代码的gist

+1

我只是做了一些基准测试,以确保compat模式不会影响性能,并惊喜于我的用例。我使用了一个带有10,000个键的散列(string => int),并使用Benchmark.bmbm获得了以下结果(似乎无法在这些注释中进行格式化):json 14.550000 0.270000 14.820000(14.855023) oj default 3.420000 0.250000 3.670000(3.684655) oj compat 3.500000 0.260000 3.760000(3.758900) – cmwright

+0

@cmwright啊非常好。过了一会儿,我确定没有任何性能问题,但我从来没有做过任何实际的基准测试。很高兴知道。这个问题似乎获得了比我预期更多的观点,那么如果我将数据添加到答案中(当然有适当的功劳),那么你会介意吗? –

+1

是的,绝对是它的。我可以张贴我下次在电脑上使用的代码的要点 – cmwright

相关问题