2010-05-30 14 views
8

Estoy intentando crear un servicio web usando Ruby Sinatra y MongoDB. Devolverá objetos JSON. Decidí usar MongoDB, en parte, porque almacena documentos internamente en una estructura "similar a JSON". Pensé que esto me facilitaría ejecutar una consulta y enviar un resultado JSON al cliente. Sin embargo, me he encontrado con problemas para convertir los resultados de MongoDB en JSON.En Ruby, MongoDB devuelve un BSON :: OrderedHash. ¿Cómo puedo convertirlo a JSON? Usar to_json da un error de "nivel de pila demasiado grande"

find_one() de MongoDB devuelve un BSON :: OrderedHash. Desde el documentation parece que esto debería comportarse de manera similar al tipo de Hash de Ruby. Cuando trato de convertirlo a JSON utilizando la función .to_json, aparece un error de "nivel de pila demasiado profundo". Tratar de convertir un idéntico funciona bien.

Este código funciona como yo esperaría:

require "json" 

my_hash = Hash.new 
my_hash[ "a" ] = "aaa" 
my_hash[ "b" ] = 9 

puts my_hash.to_json 

Este código produce `a_json ': nivel de pila demasiado profundo (SystemStackError):

require "json" 
require "bson" 

my_bson = BSON::OrderedHash.new 
my_bson[ "a" ] = "aaa" 
my_bson[ "b" ] = 9 

puts my_bson.to_json 

tratar de convertir a un hash primero no lo hizo ayuda. Mismo error.

puts my_bson.to_hash.to_json 

¿Por qué estoy recibiendo el error de nivelación demasiado profunda? Este es un hash simple. ¿Hay una forma fácil de convertir los resultados de MongoDB a JSON? No quiero escribir una función de conversión que sea específica de mis datos. Eso frustra el punto de tener una base de datos sin esquemas.

+0

Je. Al principio pensé que "BSON" en el título era un error tipográfico. Aprenda algo nuevo cada día. – Matchu

+0

Sus ejemplos están trabajando con mi configuración actual en irb. Tengo ruby ​​1.8.7 (2010-01-10 patchlevel 249) [i486-linux], irb 0.9.5 (05/04/13), bson (1.0.1), bson_ext (1.0.1). ¿El error con Bsons normales o solo con los obtenidos de una base de datos MongoDB? – ponzao

+0

No he podido obtener bson_ext para compilar en mi sistema, así que solo estoy usando bson. Es posible que intentes sin bson_ext? Tal vez eso explica la diferencia? ¿Alguien sabe si hay una versión binaria de Windows de bson_ext disponible en alguna parte para que pueda evitar el dolor de intentar que se construya? –

Respuesta

3

Pruebe esta solución:

class BSON::OrderedHash 
    def to_h 
    inject({}) { |acc, element| k,v = element; acc[k] = (if v.class == BSON::OrderedHash then v.to_h else v end); acc } 
    end 

    def to_json 
    to_h.to_json 
    end 
end 
Cuestiones relacionadas