npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

adonis4-soft-deletes

v3.0.1

Published

Basic implementation for soft deletes in AdonisJS

Downloads

22

Readme

Adonis Soft Deletes

Notes (PLEASE READ)

  • This is for Adonis v4.x
  • I'll try to recreate this package for Adonis v5 as well

Breaking changes from version 2.x.x

  • It is needed to define .withTrashed()/.onlyTrashed() before using .restore()

Notable changes from version 2.x.x

  • Every query has been changed to use tableName.fieldName format instead of just fieldName due to ambiguous field errors
  • Package now works with manyThrough relations
  • Due to core Adonis changes 2 tests are failing but are still working as intended

Introduction

This package allows you to soft delete entries in the DB meaning that they will still be there but will have 'deleted_at' set to some value and as such 'deleted'

Installation

Make sure to install it using npm or yarn.

# npm
npm i @ksgl/adonis4-soft-deletes

# yarn
yarn add @ksgl/adonis4-soft-deletes

Provider registration

Make sure to register the provider inside start/app.js file.

const providers = [
  ...
  '@ksgl/adonis4-soft-deletes/providers/SoftDeletesProvider',
  ...
]

Setup

Inside your boot() method in model

const Model = use('Model')

class Post extends Model {
  static boot () {
    super.boot()
    this.addTrait('@provider:SoftDeletes')
  }
}

Options

tableName

Type: string

Description: If you need to define table name before a field name

Default: Whatever the table name is

fieldName

Type: string

Description: If you need to define field name to use when deleting

Default: "deleted_at"

Usage

const Model = use('Model')

class Post extends Model {
  static boot () {
    super.boot()
    this.addTrait('@provider:SoftDeletes', { fieldName: "deleted_at", hideSoftDeletedRows: true })
  }
}

NOTE: Make sure that your model table has deleted_at datetime column (or whatever your fieldName name is)

NOTE: By default it hide any deleted rows, to show deleted rows by default use hideSoftDeletedRows = false to disable filtering

NOTE: If the model has this trait, upon delete() we will soft delete, if you want to delete then call forceDelete()

Custom model hooks

Depending on where you called .delete, .forceDelete(), .restore() you will get either one instance (on Model) or multiple instances (on query) as "someCustomName"

softDelete

This is a model hook fired before/after .delete()

this.addHook('beforeSoftDelete', async (someCustomName) => {
  // Do something
})

this.addHook('afterSoftDelete', async (someCustomName) => {
// Do something
})

delete (default Adonis hook)

This is a default adonis hook fired before/after real delete or in this case .forceDelete()

this.addHook('beforeDelete', async (someCustomName) => {
  // Do something
})

this.addHook('afterDelete', async (someCustomName) => {
// Do something
})

restore

This is a default adonis hook but I couldn't find any place where it is used so I've decided to use it for restore()

this.addHook('beforeRestore', async (someCustomName) => {
  // Do something
})

this.addHook('afterRestore', async (someCustomName) => {
// Do something
})

Model instance

NOTE: Upon soft delete/restore we change the $frozen property.

When we want to soft delete a model instance

 ...
 let user = await User.find(1)
 await user.delete()
 ...

When we want to restore a model instance

 ...
 let user = await User.query().withTrashed().where("id",1).first()
 await user.restore()
 ...

When we want to force delete a model instance

 ...
 let user = await User.find(1)
 await user.forceDelete()
 ...

Check if model instance is soft deleted

 ...
 let user = await User.query().withTrashed().where("id",1).first()
 let isSoftDeleted = await user.isSoftDeleted()
 ...

Model query builder

NOTE: Upon delete/restore we DO NOT change the $frozen property since it is not possible

When we want to soft delete using query

 ...
 await User.query()
 .where('country_id', 4)
 .delete()
 ...

When we want to restore using query

 ...
 await User.query()
 .where('country_id', 4)
 .onlyTrashed()
 .restore()
 ...

When we want to force delete using query

 ...
 await User.query()
 .where('country_id', 4)
 .forceDelete()
 ...

When we want to fetch non trashed users

 ...
 // We will automatically get only non trashed users
 await User.query().fetch()
 ...

When we want to fetch with trashed users

 ...
 await User.query().withTrashed().fetch()
 ...

When we want to fetch only trashed users

 ...
 await User.query().onlyTrashed().fetch()
 ...

Relationships

When we want to soft delete relations

 ...
 await ownerUser.cars().delete();
 ...

When we want to restore relations

 ...
 await  ownerUser.cars().onlyTrashed().restore();
 ...

When we want to get non trashed relations

 ...
 await  ownerUser.cars().fetch();
 ...

When we want to get all relations

 ...
 await  ownerUser.cars().withTrashed().fetch();
 ...

When we want to get onlyTrashed relations

 ...
 await  ownerUser.cars().onlyTrashed().fetch();
 ...

manyThrough relations

There are some additional things required for use with manyThrough

If you have updated_at timestamp available for Model then you need to redefine updatedAtColumn to be tableName.fieldName

 ...
class User extends Model {
  static boot() {
    super.boot()
    this.addTrait('@provider:SoftDeletes')
  }

  static get updatedAtColumn() {
    return 'users.updated_at'
  }
}
 ...

Thanks

Special thanks to the creator(s) of AdonisJS for creating such a great framework.