destroying
To destroy a model, simply call the destroy
method on the instance.
import User from 'app/models/user'
const user = await User.first()
await user.destroy()
Associations can be destroyed using destroyAssociation
:
const place = await Place.first()
await place.destroyAssociation('rooms')
// OR
await place.destroyAssociation('rooms', { and: { name: 'my room' } })
Cascading
Deletion will cascade through associations declared dependent: 'destroy'
. If each associated model is decorated with @SoftDelete (see below), then the models corresponding to that association will be soft deleted.
const deco = new Decorators<InstanceType<typeof Place>>()
export default class Place extends ApplicationModel {
@deco.HasMany('Room', { dependent: 'destroy' })
public rooms: Room[]
}
await Room.count()
// 3
const place = await Place.first()
await place.associationQuery('rooms').count()
// 3
await place.destroy()
await Room.count()
// 0
@SoftDelete
Soft deletion enables a model to be hidden, by default, from all queries, without actually being deleted from the database. This is useful for providing a "undo" deletion and "trash" functionality.
To activate soft deletion, first create a migration to add a deleted_at
column to the database:
yarn psy g:migration add-deleted-at-to-rooms deleted_at:datetime
Then apply the @SoftDelete
decorator to the Dream model class:
@SoftDelete()
export default class Place extends ApplicationModel {
...
}
NOTE: when using soft deletion, it is recommended that the default foreign key deletion constraint of 'restrict' be used:
await db.schema
.createTable('rooms')
.addColumn('id', 'bigserial', col => col.primaryKey())
.addColumn('place_id', 'bigint', col => col.references('places.id').onDelete('restrict').notNull())
.execute()
}
Loading soft deleted models
Soft deleted models can be included in queries by removing all default scopes or specfically the soft delete scope:
await Place.create({ name: 'My Place' })
await Place.count()
// 1
await Place.destroy()
await Place.count()
// 0
await Place.removeAllDefaultScopes().count()
// 1
await Place.removeDefaultScope('dream:SoftDelete').count()
// 1
Deleting @SoftDelete models from the database
A model marked @SoftDelete
can be deleted with reallyDestroy
. As with
await Place.create({ name: 'My Place' })
await Place.count()
// 1
await Place.reallyDestroy()
await Place.removeAllDefaultScopes().count()
// 0