Created
February 18, 2018 16:57
-
-
Save lorenzorapetti/38cab778eef588c3128c05a18a65e789 to your computer and use it in GitHub Desktop.
Custom validation in objection.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { Model, AjvValidator } = require('objection'); | |
const pluralize = require('pluralize'); | |
class BaseModel extends Model { | |
/** | |
* Always use timestamps as default | |
*/ | |
static get timestamps() { | |
return true; | |
} | |
/** | |
* Use the lower case, plural model class name | |
* as the table name | |
*/ | |
static get tableName() { | |
return pluralize(this.name.toLowerCase()); | |
} | |
/** | |
* Set this directory as the model path so | |
* they can get automatically imported in | |
* `relationMappings` without circular dependencies | |
*/ | |
static get modelPaths() { | |
return [__dirname]; | |
} | |
/** | |
* Override this to true whenever you want to | |
* use `$customValidate` over `$validate` | |
* | |
* @returns {Boolean} | |
*/ | |
static get hasToCustomValidate() { | |
return false; | |
} | |
/** | |
* Return an array of the required fields to validate. | |
* | |
* @param {object} queryContext The context of the query. See http://vincit.github.io/objection.js/#context | |
* @param {object} opts Options. Can be accessed to check if the query that is being | |
* executed is an insert or an update query | |
*/ | |
// eslint-disable-next-line no-unused-vars | |
static requiredFields(queryContext, opts) { | |
return []; | |
} | |
/** | |
* Create a custom validator, because we need | |
* the $data feature, see https://github.com/epoberezkin/ajv#data-reference | |
*/ | |
static createValidator() { | |
return new AjvValidator({ | |
onCreateAjv: () => {}, | |
options: { | |
$data: true, | |
allErrors: true, | |
validateSchema: false, | |
ownProperties: true, | |
v5: true, | |
coerceTypes: true, | |
removeAdditional: true, | |
}, | |
}); | |
} | |
/** | |
* Validates the model with a custom schema. | |
* This is used over `$validate` whenever we want to | |
* validate different attributes based on whether the model | |
* is being created or updated | |
*/ | |
$customValidate(queryContext, opts) { | |
const { jsonSchema } = this.constructor; | |
jsonSchema.required = this.constructor.requiredFields(queryContext, opts); | |
const validator = this.constructor.getValidator(); | |
const args = { | |
json: this.$toJson(), | |
model: this, | |
options: { mutable: true }, | |
ctx: { jsonSchema }, | |
}; | |
validator.validate(args); | |
} | |
/** | |
* Override with the ability to perform custom validation on | |
* an insert operation | |
*/ | |
$beforeInsert(queryContext) { | |
if (this.constructor.hasToCustomValidate) { | |
this.$customValidate(queryContext, { | |
isInsert: true, | |
}); | |
} | |
} | |
/** | |
* Override with the ability to perform custom validation on | |
* an update operation | |
*/ | |
$beforeUpdate(opts, queryContext) { | |
if (this.constructor.hasToCustomValidate && !opts.skipValidation) { | |
this.$customValidate(queryContext, { | |
isUpdate: true, | |
}); | |
} | |
} | |
} | |
module.exports = BaseModel; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment