diff --git a/lib/waterline/query/dql/update.js b/lib/waterline/query/dql/update.js index 27c7c274c..c0a2e188c 100644 --- a/lib/waterline/query/dql/update.js +++ b/lib/waterline/query/dql/update.js @@ -47,7 +47,7 @@ module.exports = function(criteria, values, cb) { createBelongsTo.call(this, valuesObject, function(err) { if(err) return cb(err); - beforeCallbacks.call(self, valuesObject.values, function(err) { + beforeCallbacks.call(self, valuesObject, function(err) { if(err) return cb(err); updateRecords.call(self, valuesObject, cb); }); @@ -150,23 +150,23 @@ function createBelongsTo(valuesObject, cb) { /** * Run Before* Lifecycle Callbacks * - * @param {Object} values + * @param {Object} valuesObject * @param {Function} cb */ -function beforeCallbacks(values, cb) { +function beforeCallbacks(valuesObject, cb) { var self = this; async.series([ // Run Validation with Validation LifeCycle Callbacks function(cb) { - callbacks.validate(self, values, true, cb); + callbacks.validate(self, valuesObject.values, valuesObject.criteria, true, cb); }, // Before Update Lifecycle Callback function(cb) { - callbacks.beforeUpdate(self, values, cb); + callbacks.beforeUpdate(self, valuesObject.values, valuesObject.criteria, cb); } ], cb); diff --git a/lib/waterline/query/validate.js b/lib/waterline/query/validate.js index 32d05c3e8..e1bc0cb02 100644 --- a/lib/waterline/query/validate.js +++ b/lib/waterline/query/validate.js @@ -11,13 +11,33 @@ var _ = require('lodash'), module.exports = { - validate: function(values, presentOnly, cb) { + // validate(values, [criteria], [presentOnly], cb) + validate: function(values, criteria, presentOnly, cb) { var self = this; - //Handle optional second arg - if (typeof presentOnly === 'function') { - cb = presentOnly; + var args = []; + for (var i = 0; i < arguments.length; ++i) { + if (arguments[i] !== undefined) args.push(arguments[i]); + } + + if (args.length === 2) { + // validate(values, cb) + values = args[0]; + criteria = null; + presentOnly = false; + cb = args[1]; + } else if (args.length === 3 && typeof args[1] === 'boolean') { + // validate(values, presentOnly, cb) + values = args[0]; + criteria = null; + presentOnly = args[1]; + cb = args[2]; + } else if (args.length === 3 && typeof args[1] === 'object') { + // validate(values, criteria, cb) + values = args[0]; + criteria = args[1]; presentOnly = false; + cb = args[2]; } async.series([ @@ -25,10 +45,18 @@ module.exports = { // Run Before Validate Lifecycle Callbacks function(cb) { var runner = function(item, callback) { - item.call(self, values, function(err) { - if(err) return callback(err); - callback(); - }); + if (item.length === 2) { + // Pass only 2 parameters for backwards compatibility + item.call(self, values, function(err) { + if(err) return callback(err); + callback(); + }); + } else { + item.call(self, values, criteria, function(err) { + if(err) return callback(err); + callback(); + }); + } }; async.eachSeries(self._callbacks.beforeValidate, runner, function(err) { diff --git a/lib/waterline/utils/callbacksRunner.js b/lib/waterline/utils/callbacksRunner.js index 296e67c95..0e6a067dd 100644 --- a/lib/waterline/utils/callbacksRunner.js +++ b/lib/waterline/utils/callbacksRunner.js @@ -16,13 +16,14 @@ var runner = module.exports = {}; * * @param {Object} context * @param {Object} values + * @param {Object} criteria * @param {Boolean} presentOnly * @param {Function} cb * @api public */ -runner.validate = function(context, values, presentOnly, cb) { - context.validate(values, presentOnly, cb); +runner.validate = function(context, values, criteria, presentOnly, cb) { + context.validate(values, criteria, presentOnly, cb); }; @@ -69,14 +70,20 @@ runner.afterCreate = function(context, values, cb) { * * @param {Object} context * @param {Object} values + * @param {Object} criteria * @param {Function} cb * @api public */ -runner.beforeUpdate = function(context, values, cb) { +runner.beforeUpdate = function(context, values, criteria, cb) { var fn = function(item, next) { - item.call(context, values, next); + if (item.length === 2) { + // Pass only 2 parameters for backwards compatibility + item.call(context, values, next); + } else { + item.call(context, values, criteria, next); + } }; async.eachSeries(context._callbacks.beforeUpdate, fn, cb); @@ -114,7 +121,12 @@ runner.afterUpdate = function(context, values, cb) { runner.beforeDestroy = function(context, criteria, cb) { var fn = function(item, next) { - item.call(context, criteria, next); + if (item.length === 1) { + // Pass only 1 parameter for backwards compatibility + item.call(context, next); + } else { + item.call(context, criteria, next); + } }; async.eachSeries(context._callbacks.beforeDestroy, fn, cb); diff --git a/lib/waterline/utils/schema.js b/lib/waterline/utils/schema.js index 399281404..36a855e9d 100644 --- a/lib/waterline/utils/schema.js +++ b/lib/waterline/utils/schema.js @@ -148,6 +148,7 @@ schema.normalizeCallbacks = function(context) { var i, _i, len, _len, fn, fns = {}; function defaultFn(fn) { + if (fn === 'beforeUpdate' || fn === 'beforeValidate') return function(values, criteria, next) { return next(); }; return function(values, next) { return next(); }; } diff --git a/test/unit/callbacks/beforeValidation.create.js b/test/unit/callbacks/beforeValidation.create.js index e0255ca34..e3950a0dd 100644 --- a/test/unit/callbacks/beforeValidation.create.js +++ b/test/unit/callbacks/beforeValidation.create.js @@ -5,6 +5,7 @@ describe('.beforeValidate()', function() { describe('basic function', function() { var person; + var passedCriteria; before(function(done) { var waterline = new Waterline(); @@ -15,8 +16,9 @@ describe('.beforeValidate()', function() { name: 'string' }, - beforeValidate: function(values, cb) { + beforeValidate: function(values, criteria, cb) { values.name = values.name + ' updated'; + passedCriteria = criteria; cb(); } }); @@ -49,6 +51,7 @@ describe('.beforeValidate()', function() { person.create({ name: 'test' }, function(err, user) { assert(!err); assert(user.name === 'test updated'); + assert(passedCriteria === null); done(); }); }); @@ -62,6 +65,7 @@ describe('.beforeValidate()', function() { describe('array of functions', function() { var person, status; + var passedCriteria = []; before(function(done) { var waterline = new Waterline(); @@ -74,14 +78,16 @@ describe('.beforeValidate()', function() { beforeValidate: [ // Function 1 - function(values, cb) { + function(values, criteria, cb) { values.name = values.name + ' fn1'; + passedCriteria.push(criteria); cb(); }, // Function 2 - function(values, cb) { + function(values, criteria, cb) { values.name = values.name + ' fn2'; + passedCriteria.push(criteria); cb(); } ] @@ -109,6 +115,9 @@ describe('.beforeValidate()', function() { person.create({ name: 'test' }, function(err, user) { assert(!err); assert(user.name === 'test fn1 fn2'); + assert(passedCriteria.length === 2); + assert(passedCriteria[0] === null); + assert(passedCriteria[1] === null); done(); }); }); diff --git a/test/unit/callbacks/beforeValidation.createEach.js b/test/unit/callbacks/beforeValidation.createEach.js index 1fa709ade..41c02480a 100644 --- a/test/unit/callbacks/beforeValidation.createEach.js +++ b/test/unit/callbacks/beforeValidation.createEach.js @@ -15,7 +15,7 @@ describe('.beforeValidate()', function() { name: 'string' }, - beforeValidate: function(values, cb) { + beforeValidate: function(values, criteria, cb) { values.name = values.name + ' updated'; cb(); } @@ -75,13 +75,13 @@ describe('.beforeValidate()', function() { beforeValidate: [ // Function 1 - function(values, cb) { + function(values, criteria, cb) { values.name = values.name + ' fn1'; cb(); }, // Function 2 - function(values, cb) { + function(values, criteria, cb) { values.name = values.name + ' fn2'; cb(); } diff --git a/test/unit/callbacks/beforeValidation.findOrCreate.js b/test/unit/callbacks/beforeValidation.findOrCreate.js index 3f6ce701d..7864ef0fe 100644 --- a/test/unit/callbacks/beforeValidation.findOrCreate.js +++ b/test/unit/callbacks/beforeValidation.findOrCreate.js @@ -24,7 +24,7 @@ describe('.beforeValidate()', function() { name: 'string' }, - beforeValidate: function(values, cb) { + beforeValidate: function(values, criteria, cb) { values.name = values.name + ' updated'; cb(); } @@ -135,13 +135,13 @@ describe('.beforeValidate()', function() { beforeValidate: [ // Function 1 - function(values, cb) { + function(values, criteria, cb) { values.name = values.name + ' fn1'; cb(); }, // Function 1 - function(values, cb) { + function(values, criteria, cb) { values.name = values.name + ' fn2'; cb(); } diff --git a/test/unit/callbacks/beforeValidation.findOrCreateEach.js b/test/unit/callbacks/beforeValidation.findOrCreateEach.js index b55383f70..e2c08a513 100644 --- a/test/unit/callbacks/beforeValidation.findOrCreateEach.js +++ b/test/unit/callbacks/beforeValidation.findOrCreateEach.js @@ -15,7 +15,7 @@ describe('.beforeValidate()', function() { name: 'string' }, - beforeValidate: function(values, cb) { + beforeValidate: function(values, criteria, cb) { values.name = values.name + ' updated'; cb(); } @@ -77,13 +77,13 @@ describe('.beforeValidate()', function() { beforeValidate: [ // Function 1 - function(values, cb) { + function(values, criteria, cb) { values.name = values.name + ' fn1'; cb(); }, // Function 2 - function(values, cb) { + function(values, criteria, cb) { values.name = values.name + ' fn2'; cb(); } diff --git a/test/unit/callbacks/beforeValidation.update.js b/test/unit/callbacks/beforeValidation.update.js index 6c74a3d01..e0c466bee 100644 --- a/test/unit/callbacks/beforeValidation.update.js +++ b/test/unit/callbacks/beforeValidation.update.js @@ -5,6 +5,7 @@ describe('.beforeValidate()', function() { describe('basic function', function() { var person; + var passedCriteria; before(function(done) { var waterline = new Waterline(); @@ -15,8 +16,9 @@ describe('.beforeValidate()', function() { name: 'string' }, - beforeValidate: function(values, cb) { + beforeValidate: function(values, criteria, cb) { values.name = values.name + ' updated'; + passedCriteria = criteria; cb(); } }); @@ -49,6 +51,7 @@ describe('.beforeValidate()', function() { person.update({ name: 'criteria' }, { name: 'test' }, function(err, users) { assert(!err); assert(users[0].name === 'test updated'); + assert(passedCriteria && passedCriteria.where && passedCriteria.where.name === 'criteria'); done(); }); }); @@ -62,6 +65,7 @@ describe('.beforeValidate()', function() { describe('array of functions', function() { var person, status; + var passedCriteria = []; before(function(done) { var waterline = new Waterline(); @@ -74,14 +78,16 @@ describe('.beforeValidate()', function() { beforeValidate: [ // Function 1 - function(values, cb) { + function(values, criteria, cb) { values.name = values.name + ' fn1'; + passedCriteria.push(criteria); cb(); }, // Function 2 - function(values, cb) { + function(values, criteria, cb) { values.name = values.name + ' fn2'; + passedCriteria.push(criteria); cb(); } ] @@ -109,6 +115,9 @@ describe('.beforeValidate()', function() { person.update({ name: 'criteria' }, { name: 'test' }, function(err, users) { assert(!err); assert(users[0].name === 'test fn1 fn2'); + assert(passedCriteria.length === 2); + assert(passedCriteria[0].where && passedCriteria[0].where.name === 'criteria'); + assert(passedCriteria[1].where && passedCriteria[1].where.name === 'criteria'); done(); }); });