From 342bc2f78274ceab5127f8d09e8d6447d12d94c9 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 18 Jun 2015 15:19:45 -0700 Subject: [PATCH] prevent upsert overwriting default values with applyDefaultValues option Creates a new applyDefaultValues option on the Model constructor defaulting to true, the current behaviour. Updates the dao module to pass `{ applyDefaultValues: false }` to the Model constructor during the updateOrCreate method when we assume an update is happening. --- lib/dao.js | 4 ++-- lib/model.js | 9 +++++++-- test/defaults.test.js | 22 +++++++++++++++++++++- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/lib/dao.js b/lib/dao.js index 326b64f0..58c93efb 100644 --- a/lib/dao.js +++ b/lib/dao.js @@ -445,8 +445,8 @@ DataAccessObject.updateOrCreate = DataAccessObject.upsert = function upsert(data data = ctx.data; var update = data; var inst = data; - if(!(data instanceof Model)) { - inst = new Model(data); + if (!(data instanceof Model)) { + inst = new Model(data, { applyDefaultValues: false }); } update = inst.toObject(false); diff --git a/lib/model.js b/lib/model.js index 4fa08eda..efd533ef 100644 --- a/lib/model.js +++ b/lib/model.js @@ -43,6 +43,9 @@ function ModelBaseClass(data, options) { // Default to true options.applySetters = true; } + if (!('applyDefaultValues' in options)) { + options.applyDefaultValues = true; + } this._initProperties(data, options); } @@ -51,6 +54,7 @@ function ModelBaseClass(data, options) { * @param {Object} data The data object * @param {Object} options An object to control the instantiation * @property {Boolean} applySetters Controls if the setters will be applied + * @property {Boolean} applyDefaultValues Default attributes and values will be applied * @property {Boolean} strict Set the instance level strict mode * @property {Boolean} persisted Whether the instance has been persisted * @private @@ -72,6 +76,7 @@ ModelBaseClass.prototype._initProperties = function (data, options) { options = options || {}; var applySetters = options.applySetters; + var applyDefaultValues = options.applyDefaultValues; var strict = options.strict; if(strict === undefined) { @@ -243,7 +248,7 @@ ModelBaseClass.prototype._initProperties = function (data, options) { var type = properties[p].type; // Set default values - if (propVal === undefined) { + if (applyDefaultValues && propVal === undefined) { var def = properties[p]['default']; if (def !== undefined) { if (typeof def === 'function') { @@ -265,7 +270,7 @@ ModelBaseClass.prototype._initProperties = function (data, options) { } // Set default value using a named function - if (propVal === undefined) { + if (applyDefaultValues && propVal === undefined) { var defn = properties[p].defaultFn; switch (defn) { case undefined: diff --git a/test/defaults.test.js b/test/defaults.test.js index 8c3e89a2..6a05e0c4 100644 --- a/test/defaults.test.js +++ b/test/defaults.test.js @@ -9,7 +9,8 @@ describe('defaults', function () { before(function () { Server = db.define('Server', { host: String, - port: {type: Number, default: 80} + port: {type: Number, default: 80}, + createdAt: {type: Date, default: '$now'} }); }); @@ -49,4 +50,23 @@ describe('defaults', function () { }); }); + it('should apply defaults in upsert create', function (done) { + Server.upsert({port: 8181 }, function(err, server) { + should.not.exist(err); + should.exist(server.createdAt); + done(); + }); + }); + + it('should preserve defaults in upsert update', function (done) { + Server.findOne({}, function(err, server) { + Server.upsert({id:server.id, port: 1337 }, function(err, s) { + should.not.exist(err); + (Number(1337)).should.equal(s.port); + server.createdAt.should.eql(s.createdAt); + done(); + }); + }); + }); + });