sequelize/sequelize — pull request #640 by tremby (2013-05-22 10:46:08+00:00)
Title: Add model validations option

As discussed on IRC tonight...

The existing but unused (as far as I could tell) DAO option `validate` can now have member methods which will be called with the model object's context after the other (field-specific) validations.

Only custom functions are allowed (since isInt etc wouldn't make sense in this context).

As with other custom validations, they are deemed to pass if they throw no error, or fail if an error is thrown.

Any error messages collected are added to a '_' member array of the validation result object, alongside the arrays named after any fields whose validations failed.

Example:

var Pub = Sequelize.define('Pub', {
name: { type: Sequelize.STRING },
address: { type: Sequelize.STRING },
latitude: {
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: null,
validate: { min: -90, max: 90 }
},
longitude: {
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: null,
validate: { min: -180, max: 180 }
},
}, {
validate: {
xorCoords: function() {
if ((this.latitude === null) === (this.longitude === null)) {
throw new Error('Require either both latitude and longitude or neither')
}
}
}
})

In this simple case an object fails validation if latitude or longitude is given, but not both. If we try to build one with an out of range latitude and no longitude, `raging_bullock_arms.validate()`, might return

{
'latitude': ['Invalid number: latitude'],
'_': ['Require either both latitude and longitude or neither']
}

A test is included.