2014-01-09 50 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

相關問題