Skip to content

Commit a1a58b2

Browse files
committed
gh-2314 we should be able to update fields to empty object literals
1 parent dd978b0 commit a1a58b2

File tree

2 files changed

+73
-3
lines changed

2 files changed

+73
-3
lines changed

lib/query.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1850,7 +1850,7 @@ Query.prototype._castUpdate = function _castUpdate (obj, overwrite) {
18501850
, i = ops.length
18511851
, ret = {}
18521852
, hasKeys
1853-
, val
1853+
, val;
18541854

18551855
while (i--) {
18561856
var op = ops[i];
@@ -1926,7 +1926,7 @@ Query.prototype._walkUpdatePath = function _walkUpdatePath (obj, op, pref) {
19261926
, hasKeys = false
19271927
, schema
19281928
, key
1929-
, val
1929+
, val;
19301930

19311931
var strict = 'strict' in this._mongooseOptions
19321932
? this._mongooseOptions.strict
@@ -1977,7 +1977,11 @@ Query.prototype._walkUpdatePath = function _walkUpdatePath (obj, op, pref) {
19771977
// $currentDate can take an object
19781978
obj[key] = this._castUpdateVal(schema, val, op);
19791979
} else {
1980-
hasKeys |= this._walkUpdatePath(val, op, prefix + key);
1980+
// gh-2314
1981+
// we should be able to set a schema-less field
1982+
// to an empty object literal
1983+
hasKeys |= this._walkUpdatePath(val, op, prefix + key) ||
1984+
(utils.isObject(val) && Object.keys(val).length === 0);
19811985
}
19821986
} else {
19831987
schema = ('$each' === key || '$or' === key || '$and' === key)

test/model.findOneAndUpdate.test.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,72 @@ describe('model: findOneAndUpdate:', function(){
157157
});
158158
});
159159

160+
describe('will correctly', function() {
161+
var db, ItemParentModel, ItemChildModel;
162+
163+
before(function() {
164+
db = start();
165+
var itemSpec = new Schema({
166+
item_id: {
167+
type: ObjectId, required: true, default: function() {return new DocumentObjectId();}
168+
},
169+
address: {
170+
street: String,
171+
zipcode: String
172+
},
173+
age: Number
174+
}, {_id: false});
175+
var itemSchema = new Schema({
176+
items: [itemSpec],
177+
});
178+
ItemParentModel = db.model('ItemParentModel', itemSchema);
179+
ItemChildModel = db.model('ItemChildModel', itemSpec);
180+
});
181+
182+
after(function() {
183+
db.close();
184+
});
185+
186+
it('update subdocument in array item', function(done) {
187+
var item1 = new ItemChildModel({
188+
address: {
189+
street: "times square",
190+
zipcode: "10036"
191+
}
192+
});
193+
var item2 = new ItemChildModel({
194+
address: {
195+
street: "bryant park",
196+
zipcode: "10030"
197+
}
198+
});
199+
var item3 = new ItemChildModel({
200+
address: {
201+
street: "queens",
202+
zipcode: "1002?"
203+
}
204+
});
205+
var itemParent = new ItemParentModel({items:[item1, item2, item3]});
206+
itemParent.save(function(err) {
207+
assert.ifError(err);
208+
ItemParentModel.findOneAndUpdate(
209+
{"_id": itemParent._id, "items.item_id": item1.item_id},
210+
{"$set":{ "items.$.address":{}}},
211+
{new: true},
212+
function(err, updatedDoc) {
213+
assert.ifError(err);
214+
assert.ok(updatedDoc.items);
215+
assert.ok(updatedDoc.items instanceof Array);
216+
assert.ok(updatedDoc.items.length, 3);
217+
assert.ok(Utils.isObject(updatedDoc.items[0].address));
218+
assert.ok(Object.keys(updatedDoc.items[0].address).length, 0);
219+
done();
220+
}
221+
);
222+
});
223+
});
224+
});
225+
160226
it('returns the original document', function(done){
161227
var db = start()
162228
, M = db.model(modelname, collection)

0 commit comments

Comments
 (0)