2014-01-09 14 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という名前のオプションがありますが、これはブール値ですが、trueまたはfalseのいずれかに設定すると、この点で影響がないようです。

私が今までに見つけた唯一の解決策は、で提案されているようにwith_indifferent_accessを使用することですが、いくつかのケースではハッシュの配列があります。 OjはJsonの直列化を高速化することを前提にしているので、Oj自体でこれを行う方法を見つけたいと考えているので、その配列の各ハッシュに対してそのメソッドを技術的に呼び出すことができます。最終的には、のシリアル化中にを実行するOjにオプションまたは設定があるのだろうかと思います。

答えて

9

質問を書いているうちに、答えを見つけることができました。私はStackOverflowでこの問題(特にOj宝石に関して)に関する他の答えを見つけることができないので、私は自分の状況で他人を助けることを期待してこの投稿を保管します。

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()メソッドを実装しているかどうかを確認します。 このメソッドが存在する場合は、そのメソッドがObjectのシリアル化に使用されます。 to_hash()は柔軟性が高く、より一貫した出力を生成するので、 はto_json()メソッドよりも優先されます。 to_json() またはto_hash()メソッドのいずれも存在しない場合は、Oj内部オブジェクト変数 エンコーディングが使用されます。

私はそれを正しく解釈していますのであれば、最終的にHashクラスのto_jsonメソッドを使用しているため、このソリューションは機能しそうです。

性能に影響があるかどうかは(正または負のどちらにしろ)不明ですが、少なくともアレイの場合はwith_indifferent_accessまたはto_jsonを手動で呼び出す必要がありません。

更新

パフォーマンスに関しては、cmwrightは、いくつかのベンチマークをした、そしてこれらの結果を思い付いた:compatオプションはデフォルトOjオプションと同等の少なくともあるよう

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) 

らしいですまた、平野よりもはるかに効率的です。to_json

ベンチマークコードを含むgistです。

+1

互換モードがパフォーマンスに影響を与えないことを確認するためにベンチマークを行いました。私のユースケースには驚いていました。私は10,000のキーでハッシュ(文字列=> int)を使用し、Benchmark.bmbmで次の結果を得ました(これらのコメントではフォーマットできないようです):json 14.550000 0.270000 14.820000(14.855023) ojデフォルト3.420000 0.250000 3.670000(3.684655) oj compat 3.500000 0.260000 3.760000(3.758900) – cmwright

+0

@cmwrightああ素敵です。しばらくしてもパフォーマンス上の問題はないことが確かめられましたが、実際のベンチマークを行うことは決してありませんでした。それは素晴らしいことです。この質問は私が期待していたより多くの意見を得ているようですので、私はあなたのデータを答えに追加すればいいですか? –

+1

ええ、それは絶対に行きます。私は次回にコンピュータで使用したコードの要点を投稿することができます – cmwright

関連する問題