LearnBoost/mongoose — Issue #742: Field with value == default value doesn't save when calling .save()
Author: itaylor
Created: 2012-02-21 06:16:02+00:00
State: open

Basically, when you have an object with an unset field and a default value on that field, if you set it to the same thing as the default, it won't see the change.

I think this is happening because the check for dirty doesn't see the default value as being dirty in this case.

Here's a quick and dirty test of the condition.

```javascript
var assert = require('assert')
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
mongoose.connect("mongodb://localhost/test");
var DefaultTestObject = mongoose.model("defaultTestObject",
new Schema({
score:{type:Number, "default":55}
})
);
var myTest = new DefaultTestObject();
console.log("implicitly setting score to 55");
myTest.save(function (err, doc){
assert.ok(doc.score == 55);
DefaultTestObject.findOne({}, function (err, doc){
console.log("removing score");
doc.score = undefined;
doc.save(function (err, doc, count){
DefaultTestObject.findOne({}, function (err, doc){
//doc.score = 1; //uncommenting this line causes the assertion below to pass
console.log("set score to same value as default");
doc.score = 55;
doc.save(function (err, doc, count){
assert.ok(doc.score == 55);
assert.ok(count == 1); //This is the assertion that will fail because
//Mongoose decided not to perform the update because it didn't detect a change.
//Looking in the db from the mongo console with:
//db.defaulttestobjects.find();
//{ "_id" : ObjectId("4f433251f2a1abc9f1000001") }
// Notice that the score is not set to 55.
process.exit(0);
});
});
});
});
});
```
This is problematic for people like myself who use default values to make life easier for UI programming tasks (so I never have to do checks for missing values) but have other processes that may access the DB from non-mongoose DB access, and don't know about the defaults. I had thought that I could make this safe by writing the values back to the DB on the next time the object is saved, but because of this bug, some of my values still end up unset (if they happen to have matched the default).