Here's a list of all the Sequelize hooks: https://github.com/sequelize/sequelize/blob/main/lib/hooks.js
There are a four lifecycle events that an instance can go through:
- Validate
- Create
- Destroy
- Update
And Sequelize has default methods that allows us to hook into these lifecycle events!
(1)
- beforeBulkCreate(instances, options)
- beforeBulkDestroy(options)
- beforeBulkUpdate(options) (2)
- beforeValidate(instance, options)
-------------- VALIDATE --------------
(3)
- afterValidate(instance, options) - or - validationFailed(instance, options, error) (4)
- beforeCreate(instance, options)
- beforeDestroy(instance, options)
- beforeUpdate(instance, options)
- beforeSave(instance, options)
------- CREATE, DESTROY, UPDATE -------
(5)
- afterCreate(instance, options)
- afterDestroy(instance, options)
- afterUpdate(instance, options)
- afterSave(instance, options) (6)
- afterBulkCreate(instances, options)
- afterBulkDestroy(options)
- afterBulkUpdate(options)
beforeValidate
afterValidate or validationFailed
beforeCreate / beforeUpdate / beforeSave / beforeDestroy
afterCreate / afterUpdate / afterSave / afterDestroy
If we were to use a default Sequelize hook on a model like we did in Cody's Cafe we can invoke them like so:
Coffee.beforeSave((coffeeInstance) => {
if (!coffeeInstance.ingredients.contains('love')) {
coffeeInstance.ingredients.push('love');
}
}
)
When you are querying with findAll/find you can pass a where object to filter the query. Here is a list of Sequelize operators you can use to perform complex comparisons in your Sequelize methods:
const Op = Sequelize.Op
[Op.and]: {a: 5} // AND (a = 5)
[Op.or]: [{a: 5}, {a: 6}] // (a = 5 OR a = 6)
[Op.gt]: 6, // > 6
[Op.gte]: 6, // >= 6
[Op.lt]: 10, // < 10
[Op.lte]: 10, // <= 10
[Op.ne]: 20, // != 20
[Op.eq]: 3, // = 3
[Op.not]: true, // IS NOT TRUE
[Op.between]: [6, 10], // BETWEEN 6 AND 10
[Op.notBetween]: [11, 15], // NOT BETWEEN 11 AND 15
[Op.in]: [1, 2], // IN [1, 2]
[Op.notIn]: [1, 2], // NOT IN [1, 2]
[Op.like]: '%hat', // LIKE '%hat' (%hat means a string must end with 'hat')
[Op.notLike]: '%hat' // NOT LIKE '%hat'
[Op.iLike]: '%hat' // ILIKE '%hat' (case insensitive) (PG only)
[Op.notILike]: '%hat' // NOT ILIKE '%hat' (PG only)
[Op.startsWith]: 'hat' // LIKE 'hat%'
[Op.endsWith]: 'hat' // LIKE '%hat'
[Op.substring]: 'hat' // LIKE '%hat%'
- If you are wondering what the
%hat
means it means that the string must end with 'hat'.- This is known as a regular expression (or regex) which is a sequence of characters that define a search pattern.
- If you're curious and want to learn more check out this article!
If you were to use this in a method defined on your Sequelize model like we did in Cody's Cafe (for example: to find a given ingredient) we can do that like so:
const Op = Sequelize.Op;
Coffee.findByIngredient = function (ingredient) {
return Coffee.findAll({
where: {
ingredients: {
[Sequelize.Op.contains]: [ingredient]
}
}
})
}
const Op = Sequelize.Op;
Post.findAll({
where: {
[Op.or]: [{authorId: 12}, {authorId: 13}]
}
});
//Underneath the hood this findAll method is executing this SQL query : "SELECT * FROM post WHERE authorId = 12 OR authorId = 13;"