From 2030aee6279e5f3d550de93edecc9c5c466854ab Mon Sep 17 00:00:00 2001 From: Peter Amiri Date: Mon, 5 Oct 2026 18:41:09 -0700 Subject: [PATCH 1/2] docs: note callbacks=false and declare-time checks for dependent= Co-Authored-By: Claude Opus 5.5 Signed-off-by: Peter Amiri --- cli/lucli/templates/app/.ai/models.md | 2 ++ docs/consumer-ai/.ai/models.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/cli/lucli/templates/app/.ai/models.md b/cli/lucli/templates/app/.ai/models.md index b39a9f0b61..618242ed28 100644 --- a/cli/lucli/templates/app/.ai/models.md +++ b/cli/lucli/templates/app/.ai/models.md @@ -129,6 +129,8 @@ hasMany(name="comments", dependent="delete"); On `hasOne`, `delete` and `deleteAll` both load the child and call `delete()`; `remove` and `removeAll` both go through `update()`. +`delete(callbacks=false)` on the parent skips the dependents' callbacks too. An unsupported `dependent` value throws `Wheels.InvalidArgument` when the association is declared, so a typo surfaces at app start, not on the first delete. + Order inside the parent's `delete()` transaction: the parent's `beforeDelete`, then the dependents, then the parent row, then `afterDelete`. If `beforeDelete` returns `false` nothing is deleted; if the parent delete fails, the children's changes roll back with it. `deleteAll()` on the parent without `instantiate=true` runs no callbacks and no `dependent=`. ## Bulk writes: `insertAll` / `upsertAll` diff --git a/docs/consumer-ai/.ai/models.md b/docs/consumer-ai/.ai/models.md index b39a9f0b61..618242ed28 100644 --- a/docs/consumer-ai/.ai/models.md +++ b/docs/consumer-ai/.ai/models.md @@ -129,6 +129,8 @@ hasMany(name="comments", dependent="delete"); On `hasOne`, `delete` and `deleteAll` both load the child and call `delete()`; `remove` and `removeAll` both go through `update()`. +`delete(callbacks=false)` on the parent skips the dependents' callbacks too. An unsupported `dependent` value throws `Wheels.InvalidArgument` when the association is declared, so a typo surfaces at app start, not on the first delete. + Order inside the parent's `delete()` transaction: the parent's `beforeDelete`, then the dependents, then the parent row, then `afterDelete`. If `beforeDelete` returns `false` nothing is deleted; if the parent delete fails, the children's changes roll back with it. `deleteAll()` on the parent without `instantiate=true` runs no callbacks and no `dependent=`. ## Bulk writes: `insertAll` / `upsertAll` From c8814f1085929b4d150756a83c5d4c1aed03b176 Mon Sep 17 00:00:00 2001 From: Peter Amiri Date: Mon, 5 Oct 2026 18:42:21 -0700 Subject: [PATCH 2/2] docs: the dependent= check runs when the model first loads Co-Authored-By: Claude Opus 5.5 Signed-off-by: Peter Amiri --- cli/lucli/templates/app/.ai/models.md | 2 +- docs/consumer-ai/.ai/models.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/lucli/templates/app/.ai/models.md b/cli/lucli/templates/app/.ai/models.md index 618242ed28..a6e37d4e39 100644 --- a/cli/lucli/templates/app/.ai/models.md +++ b/cli/lucli/templates/app/.ai/models.md @@ -129,7 +129,7 @@ hasMany(name="comments", dependent="delete"); On `hasOne`, `delete` and `deleteAll` both load the child and call `delete()`; `remove` and `removeAll` both go through `update()`. -`delete(callbacks=false)` on the parent skips the dependents' callbacks too. An unsupported `dependent` value throws `Wheels.InvalidArgument` when the association is declared, so a typo surfaces at app start, not on the first delete. +`delete(callbacks=false)` on the parent skips the dependents' callbacks too. An unsupported `dependent` value throws `Wheels.InvalidArgument` when the association is declared (the first time the model loads), not on the first delete. Order inside the parent's `delete()` transaction: the parent's `beforeDelete`, then the dependents, then the parent row, then `afterDelete`. If `beforeDelete` returns `false` nothing is deleted; if the parent delete fails, the children's changes roll back with it. `deleteAll()` on the parent without `instantiate=true` runs no callbacks and no `dependent=`. diff --git a/docs/consumer-ai/.ai/models.md b/docs/consumer-ai/.ai/models.md index 618242ed28..a6e37d4e39 100644 --- a/docs/consumer-ai/.ai/models.md +++ b/docs/consumer-ai/.ai/models.md @@ -129,7 +129,7 @@ hasMany(name="comments", dependent="delete"); On `hasOne`, `delete` and `deleteAll` both load the child and call `delete()`; `remove` and `removeAll` both go through `update()`. -`delete(callbacks=false)` on the parent skips the dependents' callbacks too. An unsupported `dependent` value throws `Wheels.InvalidArgument` when the association is declared, so a typo surfaces at app start, not on the first delete. +`delete(callbacks=false)` on the parent skips the dependents' callbacks too. An unsupported `dependent` value throws `Wheels.InvalidArgument` when the association is declared (the first time the model loads), not on the first delete. Order inside the parent's `delete()` transaction: the parent's `beforeDelete`, then the dependents, then the parent row, then `afterDelete`. If `beforeDelete` returns `false` nothing is deleted; if the parent delete fails, the children's changes roll back with it. `deleteAll()` on the parent without `instantiate=true` runs no callbacks and no `dependent=`.