diff --git a/lib/model.js b/lib/model.js index a2c3b2a..16e1016 100644 --- a/lib/model.js +++ b/lib/model.js @@ -266,11 +266,19 @@ lastStepModifierFunctions.$addToSet = function (obj, field, value) { if (!util.isArray(obj[field])) { throw "Can't $addToSet an element on non-array values"; } - obj[field].forEach(function (v) { - if (compareThings(v, value) === 0) { addToSet = false; } - }); + if (value !== null && typeof value === 'object' && value.$each) { + if (Object.keys(value).length > 1) { throw "Can't use another field in conjunction with $each"; } + if (!util.isArray(value.$each)) { throw "$each requires an array value"; } - if (addToSet) { obj[field].push(value); } + value.$each.forEach(function (v) { + lastStepModifierFunctions.$addToSet(obj, field, v); + }); + } else { + obj[field].forEach(function (v) { + if (compareThings(v, value) === 0) { addToSet = false; } + }); + if (addToSet) { obj[field].push(value); } + } }; diff --git a/test/model.test.js b/test/model.test.js index 45061b3..44ed540 100644 --- a/test/model.test.js +++ b/test/model.test.js @@ -438,6 +438,22 @@ describe('Model', function () { assert.deepEqual(modified, { arr: [{ b: 2 }] }); }); + it('Can use the $each modifier to add multiple values to a set at once', function () { + var obj = { arr: ['hello'] } + , modified; + + modified = model.modify(obj, { $addToSet: { arr: { $each: ['world', 'earth', 'hello', 'earth'] } } }); + assert.deepEqual(modified, { arr: ['hello', 'world', 'earth'] }); + + (function () { + modified = model.modify(obj, { $addToSet: { arr: { $each: 45 } } }); + }).should.throw(); + + (function () { + modified = model.modify(obj, { $addToSet: { arr: { $each: ['world'], unauthorized: true } } }); + }).should.throw(); + }); + }); // End of '$addToSet modifier' describe('$pop modifier', function () {