Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Ruby, MongoDB returns a BSON::OrderedHash. How to I convert it to JSON? Using to_json gives a "stack level too deep" error [closed]

Tags:

json

ruby

mongodb

I am trying to make a web service using Ruby Sinatra and MongoDB. It will return JSON objects. I decided to use MongoDB, in part, because it stores documents internally in a "JSON-like" structure. I thought this would make it easy to me to run a query and send a JSON result to the client. However, I have run into problems converting the results from MongoDB into JSON.

MongoDB's find_one() returns a BSON::OrderedHash. From the documentation it seems like this should behave similar to Ruby's Hash type. When I try to convert it to JSON using the .to_json function, I get a "stack level too deep" error. Trying to convert an identical works just fine.

This code works like I would expect:

require "json"

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

puts my_hash.to_json

This code produces `to_json': stack level too deep (SystemStackError):

require "json"
require "bson"

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

puts my_bson.to_json

Trying to convert to hash first didn't help. Same error.

puts my_bson.to_hash.to_json

Why am I getting the stack level too deep error? This is a simple hash. Is there an easy to to convert the MongoDB results to JSON? I don't want to write a conversion function that is specific to my data. That defeats the point of have a schemaless database.

like image 388
Chad DeShon Avatar asked May 30 '10 20:05

Chad DeShon


1 Answers

Try this workaround:

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
like image 168
atretkow Avatar answered Nov 07 '22 11:11

atretkow