π€ From Claude:
AhoyTrackable hangs off after_create / after_update / after_destroy, so any write that bypasses callbacks is invisible. Distinct from #2351 (which is about who is acting) β here the callback never runs at all.
Where it bites
dependent: :nullify is an update_all. Destroying a parent silently rewrites its children:
- destroying an
EventRegistration re-points its notifications and affiliations
- destroying a
FormField orphans every form_answer
- destroying an
Address nullifies the affiliations pointing at it
The destroy of the parent is recorded. The rewrite of the children isn't, so the children's history shows nothing where the data changed under them.
Direct column writes:
SectorsTaggable resets the primary flag with update_all (sectors_taggable.rb:52)
Affiliation syncs org columns with update_columns (affiliation.rb:191)
story_share_admin_controller reorders with update_columns
Recommendation
Don't chase every call β most are deliberate (that's why they skip callbacks). Fix the ones where the silence misleads:
- Registration transfer / deletion β the affiliation and notification re-pointing is exactly the kind of thing an admin later asks about.
- Form field deletion β answers changing shape without a trace is a data-integrity story, not just an audit one.
For those, either record an explicit event where the write happens, or replace the bulk write with per-record saves where the volume is small enough (it is, in both cases).
Acceptance
Destroying a registration leaves a record of what happened to its affiliations and notifications β either on their own history or on the registration's.
π€ From Claude:
AhoyTrackablehangs offafter_create/after_update/after_destroy, so any write that bypasses callbacks is invisible. Distinct from #2351 (which is about who is acting) β here the callback never runs at all.Where it bites
dependent: :nullifyis anupdate_all. Destroying a parent silently rewrites its children:EventRegistrationre-points itsnotificationsandaffiliationsFormFieldorphans everyform_answerAddressnullifies the affiliations pointing at itThe destroy of the parent is recorded. The rewrite of the children isn't, so the children's history shows nothing where the data changed under them.
Direct column writes:
SectorsTaggableresets the primary flag withupdate_all(sectors_taggable.rb:52)Affiliationsyncs org columns withupdate_columns(affiliation.rb:191)story_share_admin_controllerreorders withupdate_columnsRecommendation
Don't chase every call β most are deliberate (that's why they skip callbacks). Fix the ones where the silence misleads:
For those, either record an explicit event where the write happens, or replace the bulk write with per-record saves where the volume is small enough (it is, in both cases).
Acceptance
Destroying a registration leaves a record of what happened to its affiliations and notifications β either on their own history or on the registration's.