Repository navigation
fix(model): dependent deletes follow callbacks = false; check dependent when declared - #4394
Conversation
…nt when declared delete(callbacks = false) passed nothing on to the dependent records it deleted or removed, so their callbacks still ran. An invalid dependent value was accepted by hasMany() / hasOne() and only threw at the first delete; it now throws Wheels.InvalidArgument when the association is declared. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Peter Amiri <peter@alurium.com>
|
REQUEST CHANGES at 4a8ee44:
The new declaration validator preserves case-insensitive operation names and boolean-false values by inspection. The current regression suite covers |
deleteAll(instantiate = true), deleteOne() and updateOne() loaded their records without passing callbacks on, so afterFind / afterInitialization still ran with callbacks = false. A hasOne with dependent = "deleteAll" / "removeAll" loads its record through deleteOne() / updateOne() and got no callbacks argument at all. Both now follow the parent's callbacks; specs cover hasOne for every dependent value and the finder and transaction callbacks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Peter Amiri <peter@alurium.com>
|
Source APPROVE at ab06ed7; final gate pending. Both propagation gaps are resolved: all dependent branches now pass Evidence qualification: the suite directly tests |
Wheels Test Results28 744 tests 28 164 ✅ 9m 31s ⏱️ Results for commit a845fc6. ♻️ This comment has been updated with latest results. |
…llbacks Signed-off-by: Peter Amiri <peter@alurium.com> # Conflicts: # vendor/wheels/model/associations.cfm # vendor/wheels/model/delete.cfm
|
rev1-r1, taking the final over from rev1-r2. Delta check of the develop merge with #4397: head a845fc6. The conflict resolution is correct. I compared this PR's own diff against its merge base, before (ab06ed7, which rev1-r2 source-approved) and after (a845fc6). Every difference is in the expected place:
Full matrix 37379675857 (on ab06ed7): 32/32 legs green, |
|
FINAL: APPROVE. Head a845fc6 (ab06ed7 + the develop merge with #4397). rev1-r1, taking over from rev1-r2.
|
Fixes #4373.
delete(callbacks = false)covers dependent recordshasMany()/hasOne()withdependent = "delete"or"remove"instantiate the child records and delete or update them.delete(callbacks = false)on the parent didn't passcallbackson, so the children's callbacks still ran.$deleteDependents()now takescallbacksand passes it to every dependent call, and$delete()passes its own.The records those calls load were also found without
callbacks.deleteAll(instantiate = true),deleteOne()andupdateOne()calledfindAll()/findOne()without it, soafterFind/afterInitializationstill ran withcallbacks = false. They now pass it on, asupdateAll(instantiate = true)already did.For
hasMany,dependent = "deleteAll"/"removeAll"work in bulk and run no callbacks. ForhasOne, they go throughdeleteOne()/updateOne(), which load the record, and got nocallbacksargument at all. They now get one too.An invalid
dependentvalue fails when declaredAn unsupported value, such as
dependent = "destroy", was accepted byhasMany()/hasOne()and only threwWheels.InvalidArgumentat the first delete. It now throws the same error, with the same message, when the association is declared. Valid values are unchanged:delete,deleteAll,remove,removeAllandfalse.An app that declared an invalid value and never deleted through that association used to load; it now fails at model load, in every environment.
Specs
vendor/wheels/tests/specs/model/dependentCallbacksSpec.cfcuses dedicated test models, so no shared class changes. They areDepPost, withbeforeDelete/beforeSavelogging to the request, and three parent models:dependent = "delete","remove"and"destroy".DepPostlogsbeforeDelete,beforeSave,afterFindandafterRollback. The parent fixtures coverhasMany(delete,remove,destroy) andhasOne(all four values). Each delete runs withtransaction = "rollback".callbacks = falsewithhasManydependent = "delete"/"remove": no child callback runs (find, delete, save or rollback).callbacks = falsewithhasOneand each ofdelete,deleteAll,remove,removeAll: no child callback runs.callbacks = true: the children'safterFind, write andafterRollbackcallbacks run, forhasManyand for ahasOnewithdeleteAll.dependent = "destroy"throwsWheels.InvalidArgumentwhen the model loads.RED on develop: the two
callbacks = falsecases (3 child callbacks ran), the declaration case and the accepted-values case fail. Thecallbacks = truecontrol passes.GREEN, Lucee 7 + SQLite: full suite 6943/6943; complexity gate passes. The
hasOneand finder-callback cases were RED before the second commit (afterFindran).🤖 Generated with Claude Code