Skip to content

Add model validations option#640

Merged
sdepold merged 7 commits intosequelize:masterfrom
tremby:model-validations
May 24, 2013
Merged

Add model validations option#640
sdepold merged 7 commits intosequelize:masterfrom
tremby:model-validations

Conversation

@tremby
Copy link
Copy Markdown
Contributor

@tremby 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.

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.
As discussed on IRC. Also add task for 2.0 to change the validate()
output structure.
@sdepold
Copy link
Copy Markdown
Member

sdepold commented May 24, 2013

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

tremby added 5 commits May 23, 2013 22:37
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']
	}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great :)

sdepold added a commit that referenced this pull request May 24, 2013
@sdepold sdepold merged commit 1b55299 into sequelize:master May 24, 2013
@janmeier janmeier mentioned this pull request Jun 8, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants