2012-12-21 36 views
9

我試圖創建一組地圖的標記與to_gmaps4railseach塊的結果。在具有有效地理座標的數組上,to_gmaps4rails方法生成有效的JSON。如何JSON對象一起追加在Ruby中

我使用Mongoid和我的地理座標是一個子集,像這樣:

Account.locations.coordinates 

這裏是我的控制器代碼。 nearby_salesAccounts集合:

@json = String.new 
nearby_sales.each do |sale| 
    @json << sale.locations.to_gmaps4rails 
end 

瀏覽器抱怨我不@json形成良好。 有一個Ruby的方式來有效的JSON追加在一起嗎?

+2

難道你不想要一個數組?否則,它只會是json連續的對象,沒有逗號或周圍的結構。 –

回答

18

不能連接由to_gmaps4rails返回的JSON格式化字符串,因爲它們一旦解碼就不會生成有效的對象。

如果我有一些對象我想送:

loc1 = {"longitude" => "2.13012", "latitude" => "48.8014"} 
loc2 = {"longitude" => "-90.556", "latitude" => "41.0634"} 

,並將其轉換成JSON像to_gmaps4rails作用:

loc1_json = loc1.to_json 
=> "{\"longitude\":\"2.13012\",\"latitude\":\"48.8014\"}" 
loc2_json = loc2.to_json 
=> "{\"longitude\":\"-90.556\",\"latitude\":\"41.0634\"}" 

他們是2 JSON編碼的對象爲字符串。

拼接生成的字符串:

loc1_json + loc2_json 
=> "{\"longitude\":\"2.13012\",\"latitude\":\"48.8014\"}{\"longitude\":\"-90.556\",\"latitude\":\"41.0634\"}" 

並將它們發送到一個JSON解碼器的另一個應用程序,我會得到:

JSON[loc1_json + loc2_json] 
JSON::ParserError: 743: unexpected token at '{"longitude":"-90.556","latitude":"41.0634"}' 

解析器僅使其通過串中途才找到一個結束分隔符,知道有一個錯誤。

我可以將它們包裝在一個數組或哈希中,然後再次編碼爲JSON,但這並沒有幫助,因爲單個JSON字符串將被編碼兩次,並且需要再次解碼兩次才能返回原始數據:

JSON[([loc1_json, loc2_json]).to_json] 
=> ["{\"longitude\":\"2.13012\",\"latitude\":\"48.8014\"}", 
    "{\"longitude\":\"-90.556\",\"latitude\":\"41.0634\"}"] 

JSON[([loc1_json, loc2_json]).to_json].map{ |s| JSON[s] } 
=> [{"longitude"=>"2.13012", "latitude"=>"48.8014"}, 
    {"longitude"=>"-90.556", "latitude"=>"41.0634"}] 

這不是一個情況JSON解碼器預計,這樣會需要在客戶端上一些時髦的JavaScript來兩次使用魔法JSON解碼器環。

真正的解決方案是將它們解碼回到其天然Ruby對象第一,然後將它們重新編碼成陣列或散列,然後發送它們:

array_of_json = [loc1_json, loc2_json].map{ |s| JSON[s] }.to_json 
=> "[{\"longitude\":\"2.13012\",\"latitude\":\"48.8014\"},{\"longitude\":\"-90.556\",\"latitude\":\"41.0634\"}]" 

值被正確編碼現在,並且可以是發送到目的地瀏覽器或應用程序,那麼它可以使所產生的數據的意義,而不是作爲一個字符串數組如上,但由於數據的哈希值的數組:

JSON[array_of_json] 
=> [{"longitude"=>"2.13012", "latitude"=>"48.8014"}, 
    {"longitude"=>"-90.556", "latitude"=>"41.0634"}] 

loc1 == JSON[array_of_json][0] 
=> true 
loc2 == JSON[array_of_json][1] 
=> true 

應用,爲您的代碼,這裏的需要做什麼:

@json = [] 
nearby_sales.each do |sale| 
    @json << JSON[sale.locations.to_gmaps4rails] 
end 
@json.to_json 

這將位置解碼回它們的「pre-JSON」狀態,將它們附加到數組中,然後以JSON格式返回數組。

+0

工作完美!感謝你的工作代碼,但特別是對於偉大的解釋! – SteveO7

+0

一個問題,我希望你能幫助我。儘管json現在已經很好地形成了,但它包含了哈希數組的數組。像[[{「lat」:39,「lng」: - 104},{「lat」:39,「lng」: - 105}],[{「lat」:39,「lng」: - 104.5]]創造一個層次太深。有沒有辦法將原生哈希追加到塊內的@json? – SteveO7

+0

等待......我想我明白了。我加了.flatten!到最後一行如此; @ json.flatten!.to_json和返回瀏覽器的json看起來就像我期望的那樣。我看到一些關於使用拼合的警告可能會導致意想不到的結果,對此有何建議? – SteveO7

2
require 'json' 

@json = Array.new 
nearby_sales.each do |sale| 
    @json << sale.locations.to_gmaps4rails 
end 
@json.to_json