ReviewOS

also looking at this

stacks/bun-query-builder

docs(delete): describe soft deletes as the builder implements them

#1162
Merged glennmichael123 wants to merge docs/delete-soft-deletes into main
1 file +32 -19

Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.

docs/delete.mdmodified+32-19
Changes to docs/delete.md
@@ -57,24 +57,32 @@ await db
5757
5858## Soft Deletes
5959
60If your model supports soft deletes, records are marked as deleted instead of being removed:
60A soft-deleted row stays in the table with its `deleted_at` column set. The
61query 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,
63once the filter is switched on in your config:
6164
6265```typescript
63// Model with soft deletes enabled
64const models = {
65 User: {
66 name: 'User',
67 table: 'users',
68 softDeletes: true, // Enable soft deletes
69 // ...
66import { setConfig } from 'bun-query-builder'
67
68setConfig({
69 softDeletes: {
70 enabled: true,
71 column: 'deleted_at',
72 defaultFilter: true, // add `WHERE deleted_at IS NULL` to every selectFrom()
7073 },
71}
74})
75```
7276
73// Soft delete a record
74await db.remove('users', 1)
75// Sets deleted_at = NOW() instead of removing the record
77```typescript
78// Soft delete a record: mark it
79await db
80 .updateTable('users')
81 .set({ deleted_at: new Date().toISOString() })
82 .where({ id: 1 })
83 .execute()
7684
77// Query excluding soft deleted records (default behavior)
85// Query excluding soft deleted records (with defaultFilter on)
7886const activeUsers = await db.selectFrom('users').get()
7987
8088// Query including soft deleted records
@@ -88,9 +96,12 @@ const deletedUsers = await db
8896 .selectFrom('users')
8997 .onlyTrashed()
9098 .get()
91
9299```
93100
101On a model, `traits: { useSoftDeletes: true }` adds the column in migrations,
102and `User.delete(id)`, `User.destroy(id)` and `user.delete()` mark the row
103instead of removing it (see [Deleting by id on a Model](#deleting-by-id-on-a-model)).
104
94105## Restore Soft Deleted Records
95106
96107```typescript
@@ -113,17 +124,19 @@ await db
113124
114125```typescript
115126
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.
118129await db.remove('users', 1)
119130
120// Force delete with conditions
131// Purge every soft-deleted row
121132await db
122133 .deleteFrom('users')
123 .onlyTrashed()
124 .forceDelete()
134 .whereNotNull('deleted_at')
125135 .execute()
126136
137// The same from a model: a delete on an onlyTrashed() query purges
138await User.onlyTrashed().delete()
139
127140```
128141
129142## Deleting by id on a Model