10

ブロックto_gmaps4rails内の結果を使用してマップ マーカーのグループを作成しようとしています。each有効な地理座標を持つ配列では、to_gmaps4railsメソッドは有効な JSON を生成します。

私は Mongoid を使用しており、地理座標は次のようなサブコレクションにあります。

Account.locations.coordinates  

これが私のコントローラーコードです。nearby_salesのコレクションですAccounts:

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

@jsonブラウザーは、整形式ではないことについて不平を言っています。有効なJSONを一緒に追加するRubyの方法はありますか?

4

3 に答える 3

18

によって返される JSON 形式の文字列を連結することはできませんto_gmaps4rails。これは、一度デコードすると有効なオブジェクトにならないためです。

送信したいオブジェクトがある場合:

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\"}"

これらは、文字列として JSON でエンコードされた 2 つのオブジェクトです。

結果の文字列を連結します。

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 文字列が 2 回エンコードされ、元のデータを取得するには再度 2 回デコードする必要があるため、これは役に立ちません。

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 デコーダーが予期する状況ではないため、魔法の JSON デコーダー リングを 2 回使用するには、クライアント側でファンキーな JavaScript が必要になります。

本当の解決策は、最初にそれらをネイティブの 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

これにより、場所がデコードされて「JSON 前」の状態に戻り、配列に追加されてから、配列が JSON 形式で返されます。

于 2012-12-21T13:41:02.740 に答える
2
require 'json'

@json = Array.new
nearby_sales.each do |sale|
  @json << sale.locations.to_gmaps4rails
end
@json.to_json
于 2012-12-21T12:58:34.413 に答える