O que o Claude achou que sabia sobre callbacks do Rails
Tentei executar uma rake task para deletar registros de LineItem e seus arquivos no S3. Eu queria evitar callbacks caros em modelos pai como Order.
Pedi ajuda ao Claude. Ele me deu uma resposta confiante. Ele estava errado.
Aqui está o que aprendi sobre Rails, counter caches e por que você deve verificar os conselhos de uma IA.
O Problema
LineItem pertence a OrderItem. OrderItem pertence a Order. Ambos usam counter_cache e touch.
Deletar um LineItem dispara uma cascata. Essa cascata executa jobs pesados, como estimativas de envio e recálculos de totais.
Eu precisava interromper essa cascata para economizar CPU e custos de S3.
O Erro da IA
O Claude sugeriu usar skip_callback.
Isso é uma má ideia. O skip_callback modifica a classe globalmente. Ele afeta todas as threads do seu app. Se o seu código travar antes de você reativá-lo, seus callbacks permanecerão desativados.
Depois, tentei no_touching. Envolvi a chamada tanto em OrderItem quanto em Order para garantir.
Os testes passaram, mas o console mostrou algo diferente. O timestamp de Order ainda mudou.
A Verdadeira Razão
O problema era como o counter_cache funciona com o touch.
- Quando você usa
counter_cache: trueetouch: truejuntos, o Rails os agrupa. - Ele executa um único comando SQL puro:
UPDATE ALL. - O SQL puro ignora o ciclo de vida do ActiveRecord.
- Como ele ignora o ciclo de vida, os hooks
after_commitnão são disparados.
Isso criou um paradoxo estranho:
- Os callbacks de OrderItem não foram disparados devido ao agrupamento de SQL puro.
- Os callbacks de Order FORAM disparados porque o próximo passo na cadeia foi um
touchsimples.
A Solução
Eu só precisei envolver o "avô" no no_touching.
Order.no_touching { line_item.destroy! }
Isso impede que o touch no nível de AR chegue ao modelo Order. Não interrompe o SQL puro no OrderItem, mas isso não importa porque o agrupamento do counter_cache já pula esses callbacks.
Pontos Chave
counter_cache: true+touch: true= SQL puroUPDATE ALL.- SQL puro pula todos os hooks
after_commit. - Um
touchsimples (semcounter_cache) segue o ciclo de vida padrão do AR e dispara callbacks. - Nunca confie cegamente no código de uma IA. O Claude quer te dar uma resposta. Ele não se importa se essa resposta for uma alucinação.
Sempre teste suas suposições no console do Rails. Quebre o código de propósito para ver se ele realmente interrompe o comportamento que você deseja bloquear.
Optional learning community: https://t.me/GyaanSetuAi