New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add model validations option #640

Merged
merged 7 commits into from May 24, 2013

Conversation

2 participants
@tremby
Contributor

tremby commented May 22, 2013

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.

Add model validations option
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.
Renamed model errors key from _ to __model
As discussed on IRC. Also add task for 2.0 to change the validate()
output structure.
@sdepold

This comment has been minimized.

Member

sdepold commented May 24, 2013

upvote for replacing __model with the actual custom validation's name

tremby added some commits May 24, 2013

Put model errors alongside field errors by validation name
Instead of a hash called __model with the model validation errors, the
model validation errors are now alongside the field validation keys of
the hash, named after the validation's key in the validate array. To be
as consistent as possible, the value is an array even though it will
only ever have one member. The structure is set to change in 2.0.

Example: where there was a model validation set up like

	validate: {
		xnor: function() {
			if (this.field1 === null) === (this.field2 === null) {
				throw new Error('require both or neither')
			}
		}
	}

and field1 and field2 have some validations, validate() might return
something like

	{
		field1: [
			'must be an email address',
			'email address must be @example.com'
		],
		xnor: ['require both or neither']
	}
}.bind(this), 'Members of the validate option must be functions. Model: Foo, error with validate member notFunction')
})
it('throws an error if a custom model-wide validation has the same name as a field', function() {

This comment has been minimized.

@sdepold

sdepold May 24, 2013

Member

great :)

sdepold added a commit that referenced this pull request May 24, 2013

Merge pull request #640 from tremby/model-validations
Add model validations option

@sdepold sdepold merged commit 1b55299 into sequelize:master May 24, 2013

1 check passed

default The Travis CI build passed
Details

@janmeier janmeier referenced this pull request Jun 8, 2013

Closed

Entity level validation #247

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment