mirror of
https://github.com/strapi/strapi.git
synced 2025-07-23 17:10:08 +00:00
832 lines
14 KiB
Markdown
832 lines
14 KiB
Markdown
![]() |
---
|
||
|
title: SQL ORM
|
||
|
---
|
||
|
|
||
|
The Strapi philosophy regarding databases and ORMs is very simple: a unique ORM for SQL databases and one selected ORM for each NoSQL database.
|
||
|
|
||
|
The SQL ORM aims to provide a simple library for common tasks when querying databases in JavaScript, and forming relations between these objects, taking a lot of ideas from the the [Data Mapper Pattern](http://en.wikipedia.org/wiki/Data_mapper_pattern).
|
||
|
|
||
|
With a concise, literate codebase, the Strapi SQL ORM is simple to read, understand, and extend. It doesn't force you to use any specific validation scheme, provides flexible and efficient relation/nested-relation loading, and first class transaction support.
|
||
|
|
||
|
It's a lean Object Relational Mapper, allowing you to drop down to the [raw interface](raw.md) whenever you need a custom query that doesn't quite fit with the stock conventions.
|
||
|
|
||
|
> In this document we assume the `connection` is one of the `connections` set in your config.
|
||
|
```js
|
||
|
const connection = strapi.connections.default;
|
||
|
```
|
||
|
|
||
|
## Promises
|
||
|
|
||
|
The Strapi SQL ORM uses its own copy of the "bluebird" promise library. That means methods are chainables and return promises.
|
||
|
|
||
|
```js
|
||
|
User.forge()
|
||
|
.where('reviews', '>', 100)
|
||
|
.limit(10)
|
||
|
.offset(30)
|
||
|
.fetch()
|
||
|
.then(function (model) {
|
||
|
console.log(model.toJSON());
|
||
|
})
|
||
|
.catch(function (err) {
|
||
|
console.log(err);
|
||
|
});
|
||
|
```
|
||
|
|
||
|
## Query language basics
|
||
|
|
||
|
### Fetch a record
|
||
|
|
||
|
Example:
|
||
|
|
||
|
```js
|
||
|
User.forge({id: 123})
|
||
|
.fetch()
|
||
|
.then(function (model) {
|
||
|
console.log(model.toJSON());
|
||
|
})
|
||
|
.catch(function (err) {
|
||
|
console.log(err);
|
||
|
});
|
||
|
```
|
||
|
|
||
|
The `console.log()` will print out:
|
||
|
|
||
|
```js
|
||
|
{
|
||
|
"id": 123,
|
||
|
"firstname": "John",
|
||
|
"lastname": "Doe",
|
||
|
"age": 20
|
||
|
}
|
||
|
```
|
||
|
|
||
|
It is also possible to eager loading any specified relations named on the model:
|
||
|
|
||
|
```js
|
||
|
User.forge({id: 123})
|
||
|
.fetch({
|
||
|
withRelated: ['friends', 'likes']
|
||
|
})
|
||
|
.then(function (model) {
|
||
|
console.log(model.toJSON());
|
||
|
})
|
||
|
.catch(function (err) {
|
||
|
console.log(err);
|
||
|
});
|
||
|
```
|
||
|
|
||
|
The `console.log()` will print out:
|
||
|
|
||
|
```js
|
||
|
{
|
||
|
"id": 123,
|
||
|
"firstname": "John",
|
||
|
"lastname": "Doe",
|
||
|
"age": 20,
|
||
|
"friends": [{
|
||
|
"id": 99,
|
||
|
"firstname": "Peter",
|
||
|
"lastname": "Arrow",
|
||
|
"age": 53
|
||
|
}, {
|
||
|
"id": 48,
|
||
|
"firstname": "Andrea",
|
||
|
"lastname": "Nelson",
|
||
|
"age": 32
|
||
|
}],
|
||
|
"likes": [{
|
||
|
"post_id": 1829,
|
||
|
"date": "2016-04-22T06:00:00Z"
|
||
|
}, {
|
||
|
"post_id": 7849,
|
||
|
"date": "2016-03-22T07:32:45Z"
|
||
|
}]
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### Fetch records
|
||
|
|
||
|
Example:
|
||
|
|
||
|
```js
|
||
|
User.forge()
|
||
|
.fetchAll()
|
||
|
.then(function (model) {
|
||
|
console.log(model.toJSON());
|
||
|
})
|
||
|
.catch(function (err) {
|
||
|
console.log(err);
|
||
|
});
|
||
|
```
|
||
|
|
||
|
The `console.log()` will print out:
|
||
|
|
||
|
```js
|
||
|
[{
|
||
|
"id": 123,
|
||
|
"firstname": "John",
|
||
|
"lastname": "Doe",
|
||
|
"age": 20
|
||
|
}, {
|
||
|
"id": 99,
|
||
|
"firstname": "Peter",
|
||
|
"lastname": "Arrow",
|
||
|
"age": 53
|
||
|
}, {
|
||
|
...
|
||
|
}]
|
||
|
```
|
||
|
|
||
|
It is also possible to eager loading any specified relations named on the model:
|
||
|
|
||
|
```js
|
||
|
User.forge()
|
||
|
.fetchAll({
|
||
|
withRelated: ['friends', 'likes']
|
||
|
})
|
||
|
.then(function (model) {
|
||
|
console.log(model.toJSON());
|
||
|
})
|
||
|
.catch(function (err) {
|
||
|
console.log(err);
|
||
|
});
|
||
|
```
|
||
|
|
||
|
### Create a record
|
||
|
|
||
|
Example:
|
||
|
|
||
|
```js
|
||
|
User.forge({
|
||
|
'firstname': 'John',
|
||
|
'lastname': 'Doe',
|
||
|
'age': 20
|
||
|
})
|
||
|
.save()
|
||
|
.then(function (model) {
|
||
|
console.log(model.toJSON());
|
||
|
})
|
||
|
.catch(function (err) {
|
||
|
console.log(err);
|
||
|
});
|
||
|
```
|
||
|
|
||
|
The `console.log()` will print out:
|
||
|
|
||
|
```js
|
||
|
{
|
||
|
"id": 123,
|
||
|
"firstname": "John",
|
||
|
"lastname": "Doe",
|
||
|
"age": 20
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### Create a record with one-to-one/one-to-many relationship
|
||
|
|
||
|
The only difference between the two relationship cases will be on the database constraints layer:
|
||
|
- *one-to-one*: it will allow only one user with the sponsor ID `849`
|
||
|
- *one-to-many*: it will allow more than one user with the sponsor ID `849`
|
||
|
|
||
|
Example:
|
||
|
|
||
|
```js
|
||
|
User.forge({
|
||
|
'firstname': 'John',
|
||
|
'lastname': 'Doe',
|
||
|
'age': 20,
|
||
|
'sponsor': 849
|
||
|
})
|
||
|
.save()
|
||
|
.then(function (model) {
|
||
|
return model.fetch({
|
||
|
withRelated: 'sponsor'
|
||
|
});
|
||
|
})
|
||
|
.then(function (model) {
|
||
|
console.log(model.toJSON());
|
||
|
})
|
||
|
.catch(function (err) {
|
||
|
console.log(err);
|
||
|
});
|
||
|
```
|
||
|
|
||
|
The `console.log()` will print out:
|
||
|
|
||
|
```js
|
||
|
{
|
||
|
"id": 123,
|
||
|
"firstname": "John",
|
||
|
"lastname": "Doe",
|
||
|
"age": 20,
|
||
|
"sponsor": {
|
||
|
"id": 849,
|
||
|
"firstname": "Peter",
|
||
|
"lastname": "Arrow",
|
||
|
"age": 53
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### Create a record with many-to-many relationship
|
||
|
|
||
|
```js
|
||
|
const friend1 = User.forge({id: 1});
|
||
|
const friend2 = User.forge({id: 2});
|
||
|
|
||
|
User.forge({
|
||
|
'firstname': 'John',
|
||
|
'lastname': 'Doe',
|
||
|
'age': 20
|
||
|
})
|
||
|
.save()
|
||
|
.tap(function (model) {
|
||
|
return model.friends().attach([friend1, friend2]);
|
||
|
})
|
||
|
.then(function (model) {
|
||
|
return model.fetch({
|
||
|
withRelated: 'friends'
|
||
|
});
|
||
|
})
|
||
|
.then(function (model) {
|
||
|
console.log(model.toJSON());
|
||
|
})
|
||
|
.catch(function (err) {
|
||
|
console.log(err);
|
||
|
});
|
||
|
```
|
||
|
|
||
|
The `console.log()` will print out:
|
||
|
|
||
|
```js
|
||
|
{
|
||
|
"id": 123,
|
||
|
"firstname": "John",
|
||
|
"lastname": "Doe",
|
||
|
"age": 20,
|
||
|
"friends": [{
|
||
|
"id": 1,
|
||
|
"firstname": "Peter",
|
||
|
"lastname": "Arrow",
|
||
|
"age": 53
|
||
|
}, {
|
||
|
"id": 2,
|
||
|
"firstname": "Andrea",
|
||
|
"lastname": "Nelson",
|
||
|
"age": 32
|
||
|
}]
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### Update a record
|
||
|
|
||
|
```js
|
||
|
User.forge({
|
||
|
id: 123
|
||
|
})
|
||
|
.save({
|
||
|
'lastname': 'Does',
|
||
|
'age': 40
|
||
|
}, {path: true})
|
||
|
.then(function (model) {
|
||
|
console.log(model.toJSON());
|
||
|
})
|
||
|
.catch(function(err) {
|
||
|
reject(err);
|
||
|
});
|
||
|
```
|
||
|
|
||
|
The `console.log()` will print out:
|
||
|
|
||
|
```js
|
||
|
{
|
||
|
"id": 123,
|
||
|
"firstname": "John",
|
||
|
"lastname": "Does",
|
||
|
"age": 40,
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### Update a record with a one-to-one/one-to-many relationship
|
||
|
|
||
|
This is exactly the same as update a record without relationship.
|
||
|
|
||
|
```js
|
||
|
User.forge({
|
||
|
id: 123
|
||
|
})
|
||
|
.save({
|
||
|
'sponsor': 756
|
||
|
}, {path: true})
|
||
|
.then(function (model) {
|
||
|
return model.fetch({
|
||
|
withRelated: 'sponsor'
|
||
|
});
|
||
|
})
|
||
|
.then(function (model) {
|
||
|
console.log(model.toJSON());
|
||
|
})
|
||
|
.catch(function(err) {
|
||
|
reject(err);
|
||
|
});
|
||
|
```
|
||
|
|
||
|
The `console.log()` will print out:
|
||
|
|
||
|
```js
|
||
|
{
|
||
|
"id": 123,
|
||
|
"firstname": "John",
|
||
|
"lastname": "Does",
|
||
|
"age": 40,
|
||
|
"sponsor": {
|
||
|
"id": 756,
|
||
|
"firstname": "Martin",
|
||
|
"lastname": "Terry",
|
||
|
"age": 37
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### Update a record with a many-to-many relationship
|
||
|
|
||
|
This is also exactly the same as update a record without relationship. However, there are two cases:
|
||
|
- Add new relationship(s) to a record
|
||
|
- Remove current(s) relationship(s) to the record
|
||
|
|
||
|
#### Add new relationship(s) to a record
|
||
|
|
||
|
```js
|
||
|
const friend3 = User.forge({id: 3});
|
||
|
|
||
|
User.forge({
|
||
|
id: 123
|
||
|
})
|
||
|
.friends()
|
||
|
.attach([friend3])
|
||
|
.then(function (model) {
|
||
|
return model.fetch({
|
||
|
withRelated: 'friends'
|
||
|
});
|
||
|
})
|
||
|
.then(function (model) {
|
||
|
console.log(model.toJSON());
|
||
|
})
|
||
|
.catch(function (err) {
|
||
|
console.log(err);
|
||
|
});
|
||
|
```
|
||
|
|
||
|
The `console.log()` will print out:
|
||
|
|
||
|
```js
|
||
|
{
|
||
|
"id": 123,
|
||
|
"firstname": "John",
|
||
|
"lastname": "Doe",
|
||
|
"age": 20,
|
||
|
"friends": [{
|
||
|
"id": 1,
|
||
|
"firstname": "Peter",
|
||
|
"lastname": "Arrow",
|
||
|
"age": 53
|
||
|
}, {
|
||
|
"id": 2,
|
||
|
"firstname": "Andrea",
|
||
|
"lastname": "Nelson",
|
||
|
"age": 32
|
||
|
}, {
|
||
|
"id": 3,
|
||
|
"firstname": "Paul",
|
||
|
"lastname": "Thomas",
|
||
|
"age": 78
|
||
|
}]
|
||
|
}
|
||
|
```
|
||
|
|
||
|
#### Remove current(s) relationship(s) to a record
|
||
|
|
||
|
```js
|
||
|
const friend2 = User.forge({id: 2});
|
||
|
const friend3 = User.forge({id: 3});
|
||
|
|
||
|
User.forge({
|
||
|
id: 123
|
||
|
})
|
||
|
.friends()
|
||
|
.detach([friend2, friend3])
|
||
|
.then(function (model) {
|
||
|
return model.fetch({
|
||
|
withRelated: 'friends'
|
||
|
});
|
||
|
})
|
||
|
.then(function (model) {
|
||
|
console.log(model.toJSON());
|
||
|
})
|
||
|
.catch(function (err) {
|
||
|
console.log(err);
|
||
|
});
|
||
|
```
|
||
|
|
||
|
The `console.log()` will print out:
|
||
|
|
||
|
```js
|
||
|
{
|
||
|
"id": 123,
|
||
|
"firstname": "John",
|
||
|
"lastname": "Doe",
|
||
|
"age": 20,
|
||
|
"friends": [{
|
||
|
"id": 1,
|
||
|
"firstname": "Peter",
|
||
|
"lastname": "Arrow",
|
||
|
"age": 53
|
||
|
}]
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### Delete a record
|
||
|
|
||
|
```js
|
||
|
User.forge({
|
||
|
id: 123
|
||
|
})
|
||
|
.destroy()
|
||
|
.then(function (model) {
|
||
|
console.log(model.toJSON());
|
||
|
})
|
||
|
.catch(function(err) {
|
||
|
console.log(err);
|
||
|
});
|
||
|
```
|
||
|
|
||
|
The `console.log()` will print out:
|
||
|
|
||
|
```js
|
||
|
null
|
||
|
```
|
||
|
|
||
|
## Query options
|
||
|
|
||
|
### raw
|
||
|
|
||
|
```js
|
||
|
User.forge({
|
||
|
id: 123
|
||
|
})
|
||
|
.query(function (qb) {
|
||
|
qb.offset(0).limit(10);
|
||
|
}))
|
||
|
.fetch()
|
||
|
.then(function (model) {
|
||
|
console.log(model.toJSON());
|
||
|
})
|
||
|
.catch(function (err) {
|
||
|
console.log(err);
|
||
|
})
|
||
|
```
|
||
|
|
||
|
### count
|
||
|
|
||
|
Count the entries for a query:
|
||
|
|
||
|
```js
|
||
|
User.forge()
|
||
|
.where({
|
||
|
'age': 20
|
||
|
})
|
||
|
.count()
|
||
|
.then(function (count) {
|
||
|
console.log(count);
|
||
|
})
|
||
|
.catch(function (err) {
|
||
|
console.log(err);
|
||
|
})
|
||
|
```
|
||
|
|
||
|
### where
|
||
|
|
||
|
Adds a `where` clause to the query:
|
||
|
|
||
|
```js
|
||
|
User.forge()
|
||
|
.where({
|
||
|
'firstname': 'John',
|
||
|
'age': 20
|
||
|
})
|
||
|
.fetch()
|
||
|
.then(function (model) {
|
||
|
console.log(model.toJSON());
|
||
|
})
|
||
|
.catch(function (err) {
|
||
|
console.log(err);
|
||
|
});
|
||
|
```
|
||
|
|
||
|
### orderBy
|
||
|
|
||
|
Adds an `orderBy` clause to the query.
|
||
|
|
||
|
Using the object syntax:
|
||
|
|
||
|
```js
|
||
|
User.forge()
|
||
|
.query({
|
||
|
'orderBy': 'firstname'
|
||
|
})
|
||
|
.fetch()
|
||
|
.then(function (model) {
|
||
|
console.log(model.toJSON());
|
||
|
})
|
||
|
.catch(function (err) {
|
||
|
console.log(err);
|
||
|
});
|
||
|
```
|
||
|
|
||
|
This syntax doesn't allow to update `ASC` / `DESC` parameter. To do so, you have to use the function syntax below:
|
||
|
|
||
|
```js
|
||
|
User.forge()
|
||
|
.query(function (qb) {
|
||
|
qb.orderBy('firstname', 'desc');
|
||
|
}))
|
||
|
.fetch()
|
||
|
.then(function (model) {
|
||
|
console.log(model.toJSON());
|
||
|
})
|
||
|
.catch(function (err) {
|
||
|
console.log(err);
|
||
|
});
|
||
|
```
|
||
|
|
||
|
### groupBy
|
||
|
|
||
|
Adds an `groupBy` clause to the query:
|
||
|
|
||
|
```js
|
||
|
User.forge()
|
||
|
.query({
|
||
|
'groupBy': 'age'
|
||
|
})
|
||
|
.fetch()
|
||
|
.then(function (model) {
|
||
|
console.log(model.toJSON());
|
||
|
})
|
||
|
.catch(function (err) {
|
||
|
console.log(err);
|
||
|
});
|
||
|
```
|
||
|
|
||
|
### limit
|
||
|
|
||
|
Adds an `limit` clause to the query:
|
||
|
|
||
|
```js
|
||
|
User.forge()
|
||
|
.query({
|
||
|
'limit': 20
|
||
|
})
|
||
|
.fetch()
|
||
|
.then(function (model) {
|
||
|
console.log(model.toJSON());
|
||
|
})
|
||
|
.catch(function (err) {
|
||
|
console.log(err);
|
||
|
});
|
||
|
```
|
||
|
|
||
|
### offset
|
||
|
|
||
|
Adds an `offset` clause to the query:
|
||
|
|
||
|
```js
|
||
|
User.forge()
|
||
|
.query({
|
||
|
'offset': 10
|
||
|
})
|
||
|
.fetch()
|
||
|
.then(function (model) {
|
||
|
console.log(model.toJSON());
|
||
|
})
|
||
|
.catch(function (err) {
|
||
|
console.log(err);
|
||
|
});
|
||
|
```
|
||
|
|
||
|
## Lifecycle events
|
||
|
|
||
|
Lifecycle callbacks are functions you can define to run at certain times in a query. They are hooks that you can tap into in order to change data. Strapi exposes a handful of lifecycle callbacks by default.
|
||
|
|
||
|
Lifecycle events must be placed in your JavaScript file of your models.
|
||
|
|
||
|
### Common callbacks
|
||
|
|
||
|
#### beforeSave
|
||
|
|
||
|
Fired before an `insert` or `update` query. A promise may be returned from the event handler for async behavior. Throwing an exception from the handler will cancel the save.
|
||
|
|
||
|
Code:
|
||
|
|
||
|
```js
|
||
|
beforeSave: (model, attrs, options) => {
|
||
|
return new Promise();
|
||
|
},
|
||
|
```
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
- `model`: The model firing the event.
|
||
|
- `attrs`: Attributes that will be inserted or updated.
|
||
|
- `options`: Options object passed to `save`.
|
||
|
|
||
|
Returns: Promise.
|
||
|
|
||
|
#### afterSave
|
||
|
|
||
|
Fired after an `insert` or `update` query.
|
||
|
|
||
|
Code:
|
||
|
|
||
|
```js
|
||
|
afterSave: (model, response, options) => {
|
||
|
return new Promise();
|
||
|
},
|
||
|
```
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
- `model`: The model firing the event.
|
||
|
- `response`: The database response.
|
||
|
- `options`: Options object passed to `save`.
|
||
|
|
||
|
Returns: Promise.
|
||
|
|
||
|
### Callbacks on fetch
|
||
|
|
||
|
#### beforeFetch
|
||
|
|
||
|
Fired before a `fetch` operation. A promise may be returned from the event handler for async behavior.
|
||
|
|
||
|
Code:
|
||
|
|
||
|
```js
|
||
|
beforeFetch: (model, columns, options) => {
|
||
|
return new Promise();
|
||
|
},
|
||
|
```
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
- `model`: The model firing the event.
|
||
|
- `columns`: The columns to be retrieved by the query.
|
||
|
- `options`: Options object passed to `fetch`.
|
||
|
|
||
|
Returns: Promise.
|
||
|
|
||
|
#### afterFetch
|
||
|
|
||
|
Fired after a `fetch` operation. A promise may be returned from the event handler for async behavior.
|
||
|
|
||
|
Code:
|
||
|
|
||
|
```js
|
||
|
afterFetch: (model, response, options) => {
|
||
|
return new Promise();
|
||
|
},
|
||
|
```
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
- `model`: The model firing the event.
|
||
|
- `response`: SQL query response.
|
||
|
- `options`: Options object passed to `fetch`.
|
||
|
|
||
|
Returns: Promise. *If the handler returns a promise, `fetch` will wait for it to be resolved.*
|
||
|
|
||
|
### Callbacks on create
|
||
|
|
||
|
#### beforeCreate
|
||
|
|
||
|
Fired before `insert` query. A promise may be returned from the event handler for async behavior. Throwing an exception from the handler will cancel the save operation.
|
||
|
|
||
|
Code:
|
||
|
|
||
|
```js
|
||
|
beforeCreate: (model, attrs, options) => {
|
||
|
return new Promise();
|
||
|
},
|
||
|
```
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
- `model`: The model firing the event.
|
||
|
- `attrs`: Attributes that will be inserted.
|
||
|
- `options`: Options object passed to `save`.
|
||
|
|
||
|
Returns: Promise.
|
||
|
|
||
|
#### afterCreate
|
||
|
|
||
|
Fired after an `insert` query.
|
||
|
|
||
|
Code:
|
||
|
|
||
|
```js
|
||
|
afterCreate: (model, attrs, options) => {
|
||
|
return new Promise();
|
||
|
},
|
||
|
```
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
- `model`: The model firing the event.
|
||
|
- `attrs`: Attributes inserted.
|
||
|
- `options`: Options object passed to `save`.
|
||
|
|
||
|
Returns: Promise.
|
||
|
|
||
|
### Callbacks on update
|
||
|
|
||
|
#### beforeUpdate
|
||
|
|
||
|
Fired before an `update` query. A promise may be returned from the event handler for async behavior. Throwing an exception from the handler will cancel the save operation.
|
||
|
|
||
|
Code:
|
||
|
|
||
|
```js
|
||
|
beforeUpdate: (model, attrs, options) => {
|
||
|
return new Promise();
|
||
|
},
|
||
|
```
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
- `model`: The model firing the event.
|
||
|
- `attrs`: Attributes that will be updated.
|
||
|
- `options`: Options object passed to `save`.
|
||
|
|
||
|
Returns: Promise.
|
||
|
|
||
|
#### afterUpdate
|
||
|
|
||
|
Fired after an `update` query.
|
||
|
|
||
|
Code:
|
||
|
|
||
|
```js
|
||
|
afterUpdate: (model, attrs, options) => {
|
||
|
return new Promise();
|
||
|
},
|
||
|
```
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
- `model`: The model firing the event.
|
||
|
- `attrs`: Attributes updated.
|
||
|
- `options`: Options object passed to `save`.
|
||
|
|
||
|
Returns: Promise.
|
||
|
|
||
|
### Callbacks on destroy
|
||
|
|
||
|
#### beforeDestroy
|
||
|
|
||
|
Fired before a `delete` query. A promise may be returned from the event handler for async behavior. Throwing an exception from the handler will reject the promise and cancel the deletion.
|
||
|
|
||
|
Code:
|
||
|
|
||
|
```js
|
||
|
beforeDestroy: (model, attrs, options) => {
|
||
|
return new Promise();
|
||
|
},
|
||
|
```
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
- `model`: The model firing the event.
|
||
|
- `attrs`: Attributes that will be destroyed.
|
||
|
- `options`: Options object passed to `save`.
|
||
|
|
||
|
Returns: Promise.
|
||
|
|
||
|
#### afterDestroy
|
||
|
|
||
|
Fired before a `delete` query. A promise may be returned from the event handler for async behavior.
|
||
|
|
||
|
Code:
|
||
|
|
||
|
```js
|
||
|
afterDestroy: (model, attrs, options) => {
|
||
|
return new Promise();
|
||
|
},
|
||
|
```
|
||
|
|
||
|
Parameters:
|
||
|
|
||
|
- `model`: The model firing the event.
|
||
|
- `attrs`: Attributes destroyed.
|
||
|
- `options`: Options object passed to `save`.
|
||
|
|
||
|
Returns: Promise.
|