rails-antipattern-callback-hell
Installation
SKILL.md
Antipattern: Callback Hell
The smell
- Multiple
after_create/after_save/after_commitcallbacks doing side effects (charges, emails, jobs, external APIs) update_columnsused as a workaround to skip them- Tests must stub or skip callbacks to keep the suite fast
- "Save without notifying" requires hacks
Why it hurts
- Implicit side effects — call sites can't see what happens
- Callback ordering bugs are silent and rare-to-reproduce
- Re-saving for unrelated reasons re-fires effects
- Hard to compose alternative flows (admin imports, backfills)
The fix
- Make side effects explicit at the call site. Replace lifecycle callbacks with named methods controllers/jobs invoke
- Push async work to jobs triggered explicitly, not from
after_commit - Reserve callbacks for invariants tightly coupled to persistence:
before_validationnormalization, derived columns,dependent: :destroy— things that don't reach outside the row