Merge pull request #110 from strongloop/feature/multi-column-unique-validation
validations: support multi-key unique constraint
This commit is contained in:
commit
1f2d012842
|
@ -197,9 +197,19 @@ Validatable.validateAsync = getConfigurator('custom', {async: true});
|
||||||
* - Oracle
|
* - Oracle
|
||||||
* - MongoDB
|
* - MongoDB
|
||||||
*
|
*
|
||||||
|
* ```
|
||||||
|
* // The login must be unique across all User instances.
|
||||||
|
* User.validatesUniquenessOf('login');
|
||||||
|
*
|
||||||
|
* // Assuming SiteUser.belongsTo(Site)
|
||||||
|
* // The login must be unique within each Site.
|
||||||
|
* SiteUser.validateUniquenessOf('login', { scopedTo: ['siteId'] });
|
||||||
|
* ```
|
||||||
|
|
||||||
* @param {String} propertyName Property name to validate.
|
* @param {String} propertyName Property name to validate.
|
||||||
* @options {Object} Options
|
* @options {Object} Options
|
||||||
* @property {RegExp} with Regular expression to validate format.
|
* @property {RegExp} with Regular expression to validate format.
|
||||||
|
* @property {Array.<String>} scopedTo List of properties defining the scope.
|
||||||
* @property {String} message Optional error message if property is not valid. Default error message: "is not unique".
|
* @property {String} message Optional error message if property is not valid. Default error message: "is not unique".
|
||||||
*/
|
*/
|
||||||
Validatable.validatesUniquenessOf = getConfigurator('uniqueness', {async: true});
|
Validatable.validatesUniquenessOf = getConfigurator('uniqueness', {async: true});
|
||||||
|
@ -297,6 +307,15 @@ function validateCustom(attr, conf, err, done) {
|
||||||
function validateUniqueness(attr, conf, err, done) {
|
function validateUniqueness(attr, conf, err, done) {
|
||||||
var cond = {where: {}};
|
var cond = {where: {}};
|
||||||
cond.where[attr] = this[attr];
|
cond.where[attr] = this[attr];
|
||||||
|
|
||||||
|
if (conf && conf.scopedTo) {
|
||||||
|
conf.scopedTo.forEach(function(k) {
|
||||||
|
var val = this[k];
|
||||||
|
if (val !== undefined)
|
||||||
|
cond.where[k] = this[k];
|
||||||
|
}, this);
|
||||||
|
}
|
||||||
|
|
||||||
this.constructor.find(cond, function (error, found) {
|
this.constructor.find(cond, function (error, found) {
|
||||||
if (error) {
|
if (error) {
|
||||||
return err();
|
return err();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// This test written in mocha+should.js
|
// This test written in mocha+should.js
|
||||||
var should = require('./init.js');
|
var should = require('./init.js');
|
||||||
|
var async = require('async');
|
||||||
|
|
||||||
var j = require('../'), db, User;
|
var j = require('../'), db, User;
|
||||||
var ValidationError = j.ValidationError;
|
var ValidationError = j.ValidationError;
|
||||||
|
@ -172,6 +173,41 @@ describe('validations', function () {
|
||||||
})).should.not.be.ok;
|
})).should.not.be.ok;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should support multi-key constraint', function(done) {
|
||||||
|
var EMAIL = 'user@xample.com';
|
||||||
|
var SiteUser = db.define('SiteUser', {
|
||||||
|
siteId: String,
|
||||||
|
email: String
|
||||||
|
});
|
||||||
|
SiteUser.validatesUniquenessOf('email', { scopedTo: ['siteId'] });
|
||||||
|
async.waterfall([
|
||||||
|
function automigrate(next) {
|
||||||
|
db.automigrate(next);
|
||||||
|
},
|
||||||
|
function createSite1User(next) {
|
||||||
|
SiteUser.create(
|
||||||
|
{ siteId: 1, email: EMAIL },
|
||||||
|
next);
|
||||||
|
},
|
||||||
|
function createSite2User(user1, next) {
|
||||||
|
SiteUser.create(
|
||||||
|
{ siteId: 2, email: EMAIL },
|
||||||
|
next);
|
||||||
|
},
|
||||||
|
function validateDuplicateUser(user2, next) {
|
||||||
|
var user3 = new SiteUser({ siteId: 1, email: EMAIL });
|
||||||
|
user3.isValid(function(valid) {
|
||||||
|
valid.should.be.false;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
], function(err) {
|
||||||
|
if (err && err.name == 'ValidationError') {
|
||||||
|
console.error('ValidationError:', err.details.messages);
|
||||||
|
}
|
||||||
|
done(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('format', function () {
|
describe('format', function () {
|
||||||
|
|
Loading…
Reference in New Issue