Srikanth Venugopalan
Srikanth Venugopalan

Reputation: 9049

ruby mongodb driver push to array

Lets say I have a document Person, and I wish to add Tags to this document.

So I would like a document to look like

{ "_id" : 5,
  "tags" : ["Music", "Baseball", "Skiing"]
}

Everytime a person chooses an interest, I would like to append it to the tags list.

Here is my attempt:

require 'mongo'

client = Mongo::Connection.new
db     = client['some_app']
coll   = db['persons']
coll.update({_id: 5}, {"$push" => {tags: "PS4"}}, {upsert: true}) 

If I run this I get an exception:

/usr/local/rvm/gems/ruby-2.1.2/gems/bson-1.10.2/lib/bson/bson_c.rb:20:in `serialize': key $push must not start with '$' (BSON::InvalidKeyName)

What am I doing wrong?

Upvotes: 0

Views: 869

Answers (1)

Gary Murakami
Gary Murakami

Reputation: 3402

It looks fine to me, and works for me. The following more exhaustive test works for me, please see if it works for you, and it should help to clarify your problem, which I suspect got lost while you were posting.

test_unit.rb:

require 'mongo'
require 'test/unit'
require 'json'

class MyTest < Test::Unit::TestCase
  def setup
    @coll = Mongo::MongoClient.new['some_app']['persons']
    @coll.remove
  end

  test "BSON version" do
    assert_equal("1.10.2", CBson::VERSION, "confirm loading of C extension and version")
  end

  test "$push to existing doc" do
    json = %q{
      {
          "_id" : 5,
          "tags" : ["Music", "Baseball", "Skiing"]
      }
    }
    @coll.insert(JSON.parse(json))
    @coll.update({_id: 5}, {"$push" => {tags: "PS4"}}, {upsert: true})
    assert(@coll.find.to_a.first['tags'].include?('PS4'))
  end

  test "upsert and $push" do
    @coll.update({_id: 5}, {"$push" => {tags: "PS4"}}, {upsert: true})
    assert(@coll.find.to_a.first['tags'].include?('PS4'))
  end
end

ruby -v test_unit.rb

ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-darwin12.0]
osprey:free-59705-mongo-push gjm$ ruby test_unit.rb
Loaded suite test_unit
Started
...

    Finished in 0.019441 seconds.

3 tests, 3 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed

154.31 tests/s, 154.31 assertions/s

Upvotes: 2

Related Questions