fix(32): WR-01 fire record events for hasMany link, unlink and deferred children

hasMany link and unlink rewrote a child's foreign key (and ClearOnChange
columns) without a RecordSaved, the deferred commit attached session-created
children silently, and unlinking a session-created child deleted it without
the RecordDeleted that should follow its RecordSaved{Created}. These paths
now fire the child's events after the commit; the CRUD service carries the
registry so the deferred commit names the child's controller.
This commit is contained in:
2026-10-27 15:30:07 +01:00
parent d660cd05fa
commit 468af06c86
8 changed files with 144 additions and 26 deletions

View File

@@ -222,7 +222,7 @@ A hook or scope that has to read the database during a write should use the tran
Scope reads and writes with `pact.ListExtendQuery` and `pact.FormExtendQuery` rather than checking in a hook: the scope then applies to every route, including relation and action routes.
Other plugins do not implement these hooks to follow your records; they listen for the record events every admin write fires after its commit: `pact.RecordSaved` from create, update, tree reorder (one per moved record) and relation-manager child create and update, `pact.RecordDeleted` from delete, each row of a bulk delete and relation-manager child delete. Record and bulk actions write through your own code and fire nothing unless that code calls `cabana.EmitRecordSaved` or `cabana.EmitRecordDeleted`. See [Record events](../plugins/extending.md#record-events).
Other plugins do not implement these hooks to follow your records; they listen for the record events every admin write fires after its commit: `pact.RecordSaved` from create, update, tree reorder (one per moved record), relation-manager child create and update, and a hasMany link or unlink (for the child, with its foreign key change, also when a parent's first save attaches the children created in its form), `pact.RecordDeleted` from delete, each row of a bulk delete, relation-manager child delete and the unlink of a child created in an unsaved parent's form. Record and bulk actions write through your own code and fire nothing unless that code calls `cabana.EmitRecordSaved` or `cabana.EmitRecordDeleted`. See [Record events](../plugins/extending.md#record-events).
### Form-only values and rules