also looking at this
docs(delete): describe soft deletes as the builder implements them
#1162
1 file
+32
-19
| @@ -57,24 +57,32 @@ await db | ||
| 57 | 57 | |
| 58 | 58 | ## Soft Deletes |
| 59 | 59 | |
| 60 | If your model supports soft deletes, records are marked as deleted instead of being removed: | |
| 60 | A soft-deleted row stays in the table with its `deleted_at` column set. The | |
| 61 | query builder does not mark rows for you: every `deleteFrom()` and | |
| 62 | `db.remove()` is a real `DELETE`. What it does is hide marked rows from reads, | |
| 63 | once the filter is switched on in your config: | |
| 61 | 64 | |
| 62 | 65 | ```typescript |
| 63 | // Model with soft deletes enabled | |
| 64 | const models = { | |
| 65 | User: { | |
| 66 | name: 'User', | |
| 67 | table: 'users', | |
| 68 | softDeletes: true, // Enable soft deletes | |
| 69 | // ... | |
| 66 | import { setConfig } from 'bun-query-builder' | |
| 67 | ||
| 68 | setConfig({ | |
| 69 | softDeletes: { | |
| 70 | enabled: true, | |
| 71 | column: 'deleted_at', | |
| 72 | defaultFilter: true, // add `WHERE deleted_at IS NULL` to every selectFrom() | |
| 70 | 73 | }, |
| 71 | } | |
| 74 | }) | |
| 75 | ``` | |
| 72 | 76 | |
| 73 | // Soft delete a record | |
| 74 | await db.remove('users', 1) | |
| 75 | // Sets deleted_at = NOW() instead of removing the record | |
| 77 | ```typescript | |
| 78 | // Soft delete a record: mark it | |
| 79 | await db | |
| 80 | .updateTable('users') | |
| 81 | .set({ deleted_at: new Date().toISOString() }) | |
| 82 | .where({ id: 1 }) | |
| 83 | .execute() | |
| 76 | 84 | |
| 77 | // Query excluding soft deleted records (default behavior) | |
| 85 | // Query excluding soft deleted records (with defaultFilter on) | |
| 78 | 86 | const activeUsers = await db.selectFrom('users').get() |
| 79 | 87 | |
| 80 | 88 | // Query including soft deleted records |
| @@ -88,9 +96,12 @@ const deletedUsers = await db | ||
| 88 | 96 | .selectFrom('users') |
| 89 | 97 | .onlyTrashed() |
| 90 | 98 | .get() |
| 91 | ||
| 92 | 99 | ``` |
| 93 | 100 | |
| 101 | On a model, `traits: { useSoftDeletes: true }` adds the column in migrations, | |
| 102 | and `User.delete(id)`, `User.destroy(id)` and `user.delete()` mark the row | |
| 103 | instead of removing it (see [Deleting by id on a Model](#deleting-by-id-on-a-model)). | |
| 104 | ||
| 94 | 105 | ## Restore Soft Deleted Records |
| 95 | 106 | |
| 96 | 107 | ```typescript |
| @@ -113,17 +124,19 @@ await db | ||
| 113 | 124 | |
| 114 | 125 | ```typescript |
| 115 | 126 | |
| 116 | // Permanently delete a soft deleted record — `remove()` issues a real DELETE, | |
| 117 | // so it removes the row whether or not it was already soft-deleted. | |
| 127 | // `remove()` issues a real DELETE, so it removes the row whether or not it | |
| 128 | // was already soft-deleted. | |
| 118 | 129 | await db.remove('users', 1) |
| 119 | 130 | |
| 120 | // Force delete with conditions | |
| 131 | // Purge every soft-deleted row | |
| 121 | 132 | await db |
| 122 | 133 | .deleteFrom('users') |
| 123 | .onlyTrashed() | |
| 124 | .forceDelete() | |
| 134 | .whereNotNull('deleted_at') | |
| 125 | 135 | .execute() |
| 126 | 136 | |
| 137 | // The same from a model: a delete on an onlyTrashed() query purges | |
| 138 | await User.onlyTrashed().delete() | |
| 139 | ||
| 127 | 140 | ``` |
| 128 | 141 | |
| 129 | 142 | ## Deleting by id on a Model |