0

So, I'm using the Ruby MongoDB driver and I want to insert and object like this:

 db.insert_one({
  'game_id' => @token,
  'board' => {
    'tiles' => @board.tiles
  }
})

where @board is an instance of a Board class.

class Board
 attr_accessor :tiles
  def initialize()
    @tiles = [Tile.new, Tile.new]
  end
end

and Tile

class Tile
  def initialize()
    @x = 1, @y = 1
  end
  def to_json(options)
    {"x" => @x, "y" => @y}.to_json
  end
end

So at the end, 'tiles' field should look like this:

'tiles': [{x:1, y:1}, {x:1, y:1}]

I'm getting this error:

undefined method `bson_type' for #<Tile:0x007ff7148d2440>

The gems I'm using: 'sinatra', 'mongo (2.0.4)' and 'bson_ext' (all required using Bundler.require). Thanks!

3
  • The error is telling you that the driver doesn't know how to put a Tile instance into MongoDB, MongoDB doesn't know what to do with Tiles and no one will automatically call to_json for you. Commented Jun 11, 2015 at 2:25
  • I've tried calling to_json, but it inserts the content as a String (a json string), not as an Array. Commented Jun 11, 2015 at 8:00
  • to_json returns a string, as_json returns a Hash. Yes, the naming is a bit confusing. Sorry, that wasn't my clearest comment ever. Commented Jun 11, 2015 at 17:11

1 Answer 1

2

You can simply transform @board.tiles from collection of Objects to collection of ruby Hashes:

class Tile
  def initialize()
    @x = 1, @y = 1
  end
  def raw_data
    {"x" => @x, "y" => @y}
  end
end

db.insert_one({
  'game_id' => @token,
  'board' => {
    'tiles' => @board.tiles.map(&:raw_data)
  }
})

For more complex thing I recommend you to use mongoid http://mongoid.org/en/mongoid/

Sign up to request clarification or add additional context in comments.

2 Comments

(I cannot prove the code right now) But that would insert a (json )string and not an array, right? I'm aware of Mongoid, I just thought my problem was easy enough to use the native driver :p Thanks!
@enrmarc You are almost right. There was a problem in my solution. It was transforming tiles to array of strings. But now I modified it to return an array of hashes

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.