Validations configuration as object
Previously validations were appended to an array when configured. The format was cumbersome, and led to issues. This refactors the configuration into an object, as a property of the Model. Note that if no validations have been configured, this property is currently `undefined`.
This commit is contained in:
parent
73330113ae
commit
86ea107550
|
@ -8,8 +8,7 @@ module.exports = DataAccessObject;
|
||||||
* Module dependencies
|
* Module dependencies
|
||||||
*/
|
*/
|
||||||
var jutil = require('./jutil');
|
var jutil = require('./jutil');
|
||||||
var validations = require('./validations.js');
|
var ValidationError = require('./validations').ValidationError;
|
||||||
var ValidationError = validations.ValidationError;
|
|
||||||
var Relation = require('./relations.js');
|
var Relation = require('./relations.js');
|
||||||
var Inclusion = require('./include.js');
|
var Inclusion = require('./include.js');
|
||||||
var List = require('./list.js');
|
var List = require('./list.js');
|
||||||
|
|
|
@ -11,7 +11,7 @@ var util = require('util');
|
||||||
var jutil = require('./jutil');
|
var jutil = require('./jutil');
|
||||||
var List = require('./list');
|
var List = require('./list');
|
||||||
var Hookable = require('./hooks');
|
var Hookable = require('./hooks');
|
||||||
var validations = require('./validations.js');
|
var validations = require('./validations');
|
||||||
var _extend = util._extend;
|
var _extend = util._extend;
|
||||||
|
|
||||||
// Set up an object for quick lookup
|
// Set up an object for quick lookup
|
||||||
|
|
|
@ -25,18 +25,6 @@ exports.Validatable = Validatable;
|
||||||
function Validatable() {
|
function Validatable() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Validatable.validations = function() {
|
|
||||||
var validations = {};
|
|
||||||
(this._validations || []).forEach(function(v) {
|
|
||||||
var key = v[0], validation = v[1], options = v[3];
|
|
||||||
var copy = extend({}, validation);
|
|
||||||
copy.options = options || {};
|
|
||||||
validations[key] = validations[key] || [];
|
|
||||||
validations[key].push(copy);
|
|
||||||
});
|
|
||||||
return validations;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate presence of one or more specified properties.
|
* Validate presence of one or more specified properties.
|
||||||
* Requires a model to include a property to be considered valid; fails when validated field is blank.
|
* Requires a model to include a property to be considered valid; fails when validated field is blank.
|
||||||
|
@ -423,9 +411,10 @@ function getConfigurator(name, opts) {
|
||||||
*/
|
*/
|
||||||
Validatable.prototype.isValid = function (callback, data) {
|
Validatable.prototype.isValid = function (callback, data) {
|
||||||
var valid = true, inst = this, wait = 0, async = false;
|
var valid = true, inst = this, wait = 0, async = false;
|
||||||
|
var validations = this.constructor.validations;
|
||||||
|
|
||||||
// exit with success when no errors
|
// exit with success when no errors
|
||||||
if (!this.constructor._validations) {
|
if (typeof validations !== 'object') {
|
||||||
cleanErrors(this);
|
cleanErrors(this);
|
||||||
if (callback) {
|
if (callback) {
|
||||||
this.trigger('validate', function (validationsDone) {
|
this.trigger('validate', function (validationsDone) {
|
||||||
|
@ -447,19 +436,23 @@ Validatable.prototype.isValid = function (callback, data) {
|
||||||
var inst = this,
|
var inst = this,
|
||||||
asyncFail = false;
|
asyncFail = false;
|
||||||
|
|
||||||
this.constructor._validations.forEach(function (v) {
|
var attrs = Object.keys(validations || {});
|
||||||
if (v[2] && v[2].async) {
|
|
||||||
|
attrs.forEach(function(attr) {
|
||||||
|
var attrValidations = validations[attr] || [];
|
||||||
|
attrValidations.forEach(function(v) {
|
||||||
|
if (v.options && v.options.async) {
|
||||||
async = true;
|
async = true;
|
||||||
wait += 1;
|
wait += 1;
|
||||||
process.nextTick(function () {
|
process.nextTick(function () {
|
||||||
validationFailed(inst, v, done);
|
validationFailed(inst, attr, v, done);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (validationFailed(inst, v)) {
|
if (validationFailed(inst, attr, v)) {
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!async) {
|
if (!async) {
|
||||||
|
@ -503,10 +496,8 @@ function cleanErrors(inst) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function validationFailed(inst, v, cb) {
|
function validationFailed(inst, attr, conf, cb) {
|
||||||
var attr = v[0];
|
var opts = conf.options || {};
|
||||||
var conf = v[1];
|
|
||||||
var opts = v[2] || {};
|
|
||||||
|
|
||||||
if (typeof attr !== 'string') return false;
|
if (typeof attr !== 'string') return false;
|
||||||
|
|
||||||
|
@ -631,12 +622,12 @@ function blank(v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function configure(cls, validation, args, opts) {
|
function configure(cls, validation, args, opts) {
|
||||||
if (!cls._validations) {
|
if (!cls.validations) {
|
||||||
Object.defineProperty(cls, '_validations', {
|
Object.defineProperty(cls, 'validations', {
|
||||||
writable: true,
|
writable: true,
|
||||||
configurable: true,
|
configurable: true,
|
||||||
enumerable: false,
|
enumerable: false,
|
||||||
value: []
|
value: {}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
args = [].slice.call(args);
|
args = [].slice.call(args);
|
||||||
|
@ -651,9 +642,12 @@ function configure(cls, validation, args, opts) {
|
||||||
}
|
}
|
||||||
conf.validation = validation;
|
conf.validation = validation;
|
||||||
args.forEach(function (attr) {
|
args.forEach(function (attr) {
|
||||||
var validation = opts ? [attr, conf, opts] : [attr, conf];
|
var validation = extend({}, conf);
|
||||||
cls._validations.push(validation);
|
validation.options = opts || {};
|
||||||
|
cls.validations[attr] = cls.validations[attr] || [];
|
||||||
|
cls.validations[attr].push(validation);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function Errors() {
|
function Errors() {
|
||||||
|
|
|
@ -102,7 +102,7 @@ describe('manipulation', function () {
|
||||||
|
|
||||||
Person.validatesPresenceOf('name');
|
Person.validatesPresenceOf('name');
|
||||||
Person.create(batch,function (errors, persons) {
|
Person.create(batch,function (errors, persons) {
|
||||||
delete Person._validations;
|
delete Person.validations;
|
||||||
should.exist(errors);
|
should.exist(errors);
|
||||||
errors.should.have.lengthOf(batch.length);
|
errors.should.have.lengthOf(batch.length);
|
||||||
should.not.exist(errors[0]);
|
should.not.exist(errors[0]);
|
||||||
|
|
|
@ -39,7 +39,7 @@ describe('validations', function () {
|
||||||
|
|
||||||
beforeEach(function (done) {
|
beforeEach(function (done) {
|
||||||
User.destroyAll(function () {
|
User.destroyAll(function () {
|
||||||
delete User._validations;
|
delete User.validations;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -67,7 +67,7 @@ describe('validations', function () {
|
||||||
describe('lifecycle', function () {
|
describe('lifecycle', function () {
|
||||||
|
|
||||||
it('should work on create', function (done) {
|
it('should work on create', function (done) {
|
||||||
delete User._validations;
|
delete User.validations;
|
||||||
User.validatesPresenceOf('name');
|
User.validatesPresenceOf('name');
|
||||||
User.create(function (e, u) {
|
User.create(function (e, u) {
|
||||||
should.exist(e);
|
should.exist(e);
|
||||||
|
@ -79,7 +79,7 @@ describe('validations', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work on update', function (done) {
|
it('should work on update', function (done) {
|
||||||
delete User._validations;
|
delete User.validations;
|
||||||
User.validatesPresenceOf('name');
|
User.validatesPresenceOf('name');
|
||||||
User.create({name: 'Valid'}, function (e, d) {
|
User.create({name: 'Valid'}, function (e, d) {
|
||||||
d.updateAttribute('name', null, function (e) {
|
d.updateAttribute('name', null, function (e) {
|
||||||
|
@ -95,7 +95,7 @@ describe('validations', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return error code', function (done) {
|
it('should return error code', function (done) {
|
||||||
delete User._validations;
|
delete User.validations;
|
||||||
User.validatesPresenceOf('name');
|
User.validatesPresenceOf('name');
|
||||||
User.create(function (e, u) {
|
User.create(function (e, u) {
|
||||||
should.exist(e);
|
should.exist(e);
|
||||||
|
@ -112,7 +112,7 @@ describe('validations', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should include validation messages in err.message', function(done) {
|
it('should include validation messages in err.message', function(done) {
|
||||||
delete User._validations;
|
delete User.validations;
|
||||||
User.validatesPresenceOf('name');
|
User.validatesPresenceOf('name');
|
||||||
User.create(function (e, u) {
|
User.create(function (e, u) {
|
||||||
should.exist(e);
|
should.exist(e);
|
||||||
|
@ -122,7 +122,7 @@ describe('validations', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should include model name in err.message', function(done) {
|
it('should include model name in err.message', function(done) {
|
||||||
delete User._validations;
|
delete User.validations;
|
||||||
User.validatesPresenceOf('name');
|
User.validatesPresenceOf('name');
|
||||||
User.create(function (e, u) {
|
User.create(function (e, u) {
|
||||||
should.exist(e);
|
should.exist(e);
|
||||||
|
@ -133,9 +133,9 @@ describe('validations', function () {
|
||||||
|
|
||||||
it('should return validation metadata', function() {
|
it('should return validation metadata', function() {
|
||||||
var expected = {name:[{validation: 'presence', options: {}}]};
|
var expected = {name:[{validation: 'presence', options: {}}]};
|
||||||
delete User._validations;
|
delete User.validations;
|
||||||
User.validatesPresenceOf('name');
|
User.validatesPresenceOf('name');
|
||||||
var validations = User.validations();
|
var validations = User.validations;
|
||||||
validations.should.eql(expected);
|
validations.should.eql(expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue