Hooks (also known as callbacks or lifecycle events), are functions which are called before and after calls in sequelize are executed. For example, if you want to always set a value on a model before saving it, you can add a `beforeUpdate` hook.
For a full list of hooks, see [Hooks API](/api/hooks).
## Order of Operations
```
...
...
@@ -32,9 +34,9 @@ Hooks (also known as callbacks or lifecycle events), are functions which are cal
```
## Declaring Hooks
Arguments to hooks are passed by reference. This means, that you can change the values, and this will be reflected in the insert / update statement. A hook may contain async actions - in this case the hook function should return a promise.
There are currently three ways to programmatically add hooks. A hook function always runs asynchronousĺy, and can be resolved either by calling a callback (passed as the last argument),
or by returning a promise.
There are currently three ways to programmatically add hooks:
```js
// Method 1 via the .define() method
...
...
@@ -46,29 +48,18 @@ var User = sequelize.define('User', {
Global hooks are hooks which are run for all models. They can define behaviours that you want for all your models, and are especially useful for plugins. They can be defined in two ways, which have slightly different semantics:
### Sequelize.options.define (default hook)
```js
varsequelize=newSequelize(...,{
define:{
hooks:{
beforeCreate:function(){
// Do stuff
}
}
}
});
```
This adds a default hook to all models, which is run if the model does not define its own `beforeCreate` hook:
```js
varUser=sequelize.define('user');
varProject=sequelize.define('project',{},{
hooks:{
beforeCreate:function(){
// Do other stuff
}
}
});
User.create()// Runs the global hook
Project.create()// Runs its own hook (because the global hook is overwritten)
```
### Sequelize.addHook (permanent hook)
```js
sequelize.addHook('beforeCreate',function(){
// Do stuff
});
```
This hooks is always run before create, regardless of whether the model specifies its own `beforeCreate` hook:
```js
var User = sequelize.define('user');
var Project = sequelize.define('project', {}, {
hooks: {
beforeCreate: function () {
// Do other stuff
}
}
});
User.create() // Runs the global hook
Project.create() // Runs its own hook, followed by the global hook
```
Local hooks are always run before global hooks.
### Instance hooks
The following hooks will emit whenever you're editing a single object...
The following hooks will emit whenever you're editing a single object
This code will run beforeDestroy/afterDestroy on the Tasks table. Sequelize, by default, will try to optimize your queries as much as possible.
When calling cascade on delete, Sequelize will simply execute a
This code will run beforeDestroy/afterDestroy on the Tasks table. Sequelize, by default, will try to optimize your queries as much as possible. When calling cascade on delete, Sequelize will simply execute a
@@ -221,29 +263,6 @@ DELETE FROM `table` WHERE associatedIdentifiier = associatedIdentifier.primaryKe
However, adding `hooks: true` explicitly tells Sequelize that optimization is not of your concern and will perform a `SELECT` on the associated objects and destroy each instance one by one in order to be able to call the hooks with the right parameters.
## Promises and callbacks
Sequelize will look at the function length of your hook callback to determine whether or not you're using callbacks or promises.
```js
// Will stall if the condition isn't met since the callback is never called
returncallback("You can't grant this user an access level above 10!");
}
});
// Will never stall since returning undefined will act as a resolved promise with an undefined value
User.beforeCreate(function(user,options){
if(user.accessLevel>10&&user.username!=="Boss"){
returnthrownewError("You can't grant this user an access level above 10!");
}
if(something){
returnPromise.reject();
}
});
```
## A Note About Transactions
Note that many model operations in Sequelize allow you to specify a transaction in the options parameter of the method. If a transaction _is_ specified in the original call, it will be present in the options parameter passed to the hook function. For example, consider the following snippet: