diff --git a/lib/model.js b/lib/model.js index 370fdb3..9752814 100644 --- a/lib/model.js +++ b/lib/model.js @@ -237,6 +237,17 @@ lastStepModifierFunctions.$push = function (obj, field, value) { obj[field].push(value); }; +// Add an element to an array field only if it is not already in it +// No modification if the element is already in the array +// Note that it doesn't check whether the original array contains duplicates +lastStepModifierFunctions.$addToSet = function (obj, field, value) { + // Create the array if it doesn't exist + if (!obj.hasOwnProperty(field)) { obj[field] = []; } + + if (!util.isArray(obj[field])) { throw "Can't $addToSet an element on non-array values"; } + if (obj[field].indexOf(value) === -1) { obj[field].push(value); } +}; + // Increment a numeric field's value lastStepModifierFunctions.$inc = function (obj, field, value) { if (typeof value !== 'number') { throw value + " must be a number"; } diff --git a/test/model.test.js b/test/model.test.js index 06242b9..dd2b0f7 100644 --- a/test/model.test.js +++ b/test/model.test.js @@ -378,6 +378,39 @@ describe('Model', function () { }); // End of '$push modifier' + describe('$addToSet modifier', function () { + + it('Can add an element to a set', function () { + var obj = { arr: ['hello'] } + , modified; + + modified = model.modify(obj, { $addToSet: { arr: 'world' } }); + assert.deepEqual(modified, { arr: ['hello', 'world'] }); + + obj = { arr: ['hello'] }; + modified = model.modify(obj, { $addToSet: { arr: 'hello' } }); + assert.deepEqual(modified, { arr: ['hello'] }); + }); + + it('Can add an element to a non-existent set and will create the array', function () { + var obj = { arr: [] } + , modified; + + modified = model.modify(obj, { $addToSet: { arr: 'world' } }); + assert.deepEqual(modified, { arr: ['world'] }); + }); + + it('Throw if we try to addToSet to a non-array', function () { + var obj = { arr: 'hello' } + , modified; + + (function () { + modified = model.modify(obj, { $addToSet: { arr: 'world' } }); + }).should.throw(); + }); + + }); // End of '$addToSet modifier' + }); // ==== End of 'Modifying documents' ==== //