Apa yang Claude Sangka Dia Tahu Tentang Rails Callbacks

Saya cuba menjalankan tugasan rake untuk memadam rekod LineItem dan fail S3 berkaitan. Saya ingin mengelakkan callback yang memakan kos tinggi pada model induk seperti Order.

Saya meminta bantuan Claude. Ia memberikan jawapan yang penuh yakin. Namun, ia salah.

Inilah apa yang saya pelajari tentang Rails, counter cache, dan mengapa anda mesti mengesahkan nasihat AI.

Masalahnya LineItem belongs to OrderItem. OrderItem belongs to Order. Kedua-duanya menggunakan counter_cache dan touch. Memadam LineItem mencetuskan rantaian (cascade). Rantaian ini menjalankan tugasan berat seperti anggaran penghantaran dan pengiraan semula jumlah. Saya perlu menghentikan rantaian ini untuk menjimatkan kos CPU dan S3.

Kesilapan AI Claude mencadangkan penggunaan skip_callback. Ini adalah idea yang buruk. skip_callback mengubah kelas secara global. Ia menjejaskan setiap thread dalam aplikasi anda. Jika kod anda terhenti (crash) sebelum anda mengaktifkannya semula, callback anda akan kekal tidak berfungsi.

Saya kemudian mencuba no_touching. Saya membungkus (wrap) panggilan tersebut dalam OrderItem dan Order untuk keselamatan. Ujian lulus, tetapi konsol menunjukkan sesuatu yang berbeza. Cap masa (timestamp) Order masih berubah.

Sebab Sebenar Isunya adalah bagaimana counter_cache berfungsi dengan touch.

  • Apabila anda menggunakan counter_cache: true dan touch: true bersama-sama, Rails menggabungkannya (bundles).
  • Ia menjalankan satu arahan raw SQL UPDATE ALL.
  • Raw SQL memintas (bypasses) kitaran hayat (lifecycle) ActiveRecord.
  • Kerana ia memintas kitaran hayat, hook after_commit tidak akan dicetuskan.

Ini mewujudkan paradoks yang pelik:

  • Callback OrderItem tidak dicetuskan disebabkan oleh gabungan raw SQL tersebut.
  • Callback Order BERJAYA dicetuskan kerana langkah seterusnya dalam rantaian tersebut adalah touch biasa.

Penyelesaian Saya hanya perlu membungkus grandparent dalam no_touching.

Order.no_touching { line_item.destroy! }

Ini menghalang touch pada tahap AR daripada sampai ke model Order. Ia tidak menghentikan raw SQL pada OrderItem, tetapi itu tidak menjadi masalah kerana gabungan counter cache sudah pun melangkau callback tersebut.

Pengajaran Utama

  • counter_cache: true + touch: true = raw SQL UPDATE ALL.
  • Raw SQL melangkau semua hook after_commit.
  • touch biasa (tanpa counter cache) mengikut kitaran hayat AR standard dan mencetuskan callback.
  • Jangan sesekali mempercayai kod AI secara membuta tuli. Claude mahu memberikan anda jawapan. Ia tidak peduli jika jawapan itu adalah halusinasi.

Sentiasa uji andaian anda dalam konsol Rails. Rosakkan kod dengan sengaja untuk melihat sama ada ia benar-benar menghentikan tingkah laku yang ingin anda sekat.

Sumber: https://dev.to/husteadrobert/what-claude-thought-he-knew-about-rails-callbacks-and-how-console-testing-proved-him-wrong-j20

Komuniti pembelajaran pilihan: https://t.me/GyaanSetuAi