问题摘要:我正在尝试使用Oj gem将哈希序列化为JSON。看来Oj不会自动将哈希的符号键转换为字符串。我想知道Oj是否可以在序列化期间选择“字符串化”?

这是我的哈希示例:

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,因此,我希望找到一种在服务器序列化期间对 key 进行字符串化的方法。

Oj有一个名为symbol_keys的选项,它是一个 bool 值,但是将其设置为truefalse似乎对此没有影响。

到目前为止,我发现的唯一解决方案是按照this answer的建议使用with_indifferent_access,但是在某些情况下,我会使用哈希数组。尽管我可以从技术上为该数组中的每个哈希调用该方法,但考虑到Oj旨在加快Json序列化的速度,我希望找到一种使用Oj本身来实现此目的的方法。最终,我想知道Oj中是否有选项或设置可以在序列化期间执行此操作。

最佳答案

当我写问题时,我能够找到答案。由于我在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模式定义如下:



因此,如果我正确地解释了这一点,则该解决方案似乎可行,因为它最终使用了to_json类的Hash方法。

我不确定是否会影响性能(正面或负面),但是至少在使用数组的情况下,它使我不必手动调用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

10-05 22:16