save / update a (Moped) BSON::Document with ruby

1.5k Views Asked by At

I tried many ways to update an existing bson document, but it never changes in my mongodb:

col = db["collection"]
col.insert({"ben": 1})
doc = col.find().to_a.first
# => {"_id"=>BSON::ObjectId('556c7f1b167e70640070a4d9'), "ben"=>1}

first attempt to update:

doc.merge!({"ben": 5, "ams": 6})
col.find().to_a.first
# => {"_id"=>BSON::ObjectId('556c7f1b167e70640070a4d9'), "ben"=>1}

second attempt to update:

doc.update({"ben": 5, "ams": 6})
col.find().to_a.first
# => {"_id"=>BSON::ObjectId('556c7f1b167e70640070a4d9'), "ben"=>1}

third attempt...

doc["ben"] = 5
doc["ams"] = 6
doc.save
# NoMethodError: undefined method `save' for #<BSON::Document:0x00000003f284d0>

As you can see, none of the above works for me. I couldn't find any other suggestions by a google search. Do yo know ways to update my document? Is it possible?

1

There are 1 best solutions below

2
On BEST ANSWER

As soon as you do this:

col.find().to_a
#          ^^^^

you're working with a simple array of Ruby hashes that have no connection to the database. So when you say:

doc.update({"ben": 5, "ams": 6})

you're calling Hash#update. If you want to update something, you'd call update on what find returns:

col.find.update(:$set => { 'ben' => 5, 'ams' => 6 })

or if you want to replace the entire document:

col.find.update('ben' => 5, 'ams' => 6)

You'd usually tell find which specific document you want of course.

Note that update only updates the first matching document it finds, if you want to update all matching documents then you'd use update_all.