Callback di Ruby on Rails adalah method yang dipanggil otomatis pada momen tertentu dalam siklus hidup objek, misalnya sebelum atau sesudah disimpan ke database. Kalau kamu baru belajar Rails, callback bisa terasa seperti sihir: tiba-tiba ada kode yang jalan tanpa kamu panggil. Memahami callback penting agar aplikasi tidak berperilaku aneh.
Pembahasan berikut mencakup jenis-jenis callback, urutan eksekusinya, jebakan yang sering dialami pemula, sampai kapan sebaiknya memilih pendekatan lain.
Apa Itu Callback di Ruby on Rails?
Callback adalah hook yang disediakan ActiveRecord, komponen Rails untuk berinteraksi dengan database. Kamu bisa menempelkan kode pada objek model dan kode itu akan dijalankan pada titik tertentu, misalnya sebelum validasi, setelah penyimpanan, atau sebelum penghapusan.
Contoh sederhana: kamu punya model User dan ingin mengirim email selamat datang setelah user baru dibuat. Daripada memanggil method pengiriman email di controller, kamu bisa menaruhnya di callback after_create.
class User < ApplicationRecord
after_create :send_welcome_email
private
def send_welcome_email
UserMailer.welcome(self).deliver_later
end
end
Dengan begitu, setiap kali user baru tersimpan, email otomatis terkirim. Kamu tidak perlu mengingatnya di setiap tempat yang membuat user.
Jenis-Jenis Callback yang Sering Dipakai
Rails menyediakan banyak callback, tetapi ada beberapa yang paling sering muncul di kode sehari-hari.
Callback Sebelum dan Sesudah Validasi
before_validation: dijalankan sebelum validasi. Berguna untuk membersihkan data, misalnya menghapus spasi di awal dan akhir string.after_validation: dijalankan setelah validasi. Bisa dipakai untuk menambahkan error kustom.
Callback Sekitar Penyimpanan
before_save: sebelum objek disimpan, baik create maupun update.after_save: setelah objek disimpan.before_createdanafter_create: hanya saat create.before_updatedanafter_update: hanya saat update.
Callback Sekitar Penghapusan
before_destroy: sebelum objek dihapus. Sering dipakai untuk menghapus data terkait atau mencegah penghapusan jika ada dependensi.after_destroy: setelah objek dihapus.
Callback Setelah Inisialisasi
after_initialize dipanggil setiap kali objek baru dibuat, baik dari database maupun dari new. Berguna untuk memberi nilai default pada atribut.
Urutan Eksekusi Callback
Callback dijalankan dalam urutan tertentu. Untuk operasi create, urutannya kira-kira: before_validation, after_validation, before_save, before_create, after_create, after_save, after_commit. Memahami urutan ini penting agar tidak bingung ketika ada callback yang tidak jalan seperti yang diharapkan.
Jika kamu mendefinisikan beberapa callback dengan jenis yang sama, Rails menjalankannya sesuai urutan definisi. Kamu juga bisa memakai prepend: true supaya callback tertentu jalan lebih dulu.
Kapan Sebaiknya Menggunakan Callback?
Callback cocok untuk logika yang memang harus selalu terjadi pada model, terlepas dari konteks pemanggilan. Contohnya:
- Normalisasi data (misalnya mengubah email menjadi huruf kecil).
- Mengisi atribut turunan (misalnya slug dari judul).
- Mencatat log aktivitas.
Kalau logika terlalu kompleks atau melibatkan banyak model lain, callback membuat kode sulit dilacak. Di titik itu, service object atau pattern lain lebih masuk akal.
Jebakan Umum dan Cara Menghindarinya
Pemula sering terjebak dalam beberapa masalah saat menggunakan callback. Berikut beberapa di antaranya.
1. Callback yang Memicu Callback Lain
Misalnya, callback after_save pada model A memperbarui model B, yang kemudian memicu callback pada model B, dan seterusnya. Rantai ini bisa menyebabkan infinite loop atau performa lambat. Solusinya, batasi callback pada operasi yang benar-benar perlu, atau gunakan after_commit untuk menghindari efek samping di tengah transaksi.
2. Callback yang Menggagalkan Penyimpanan
Callback before_save yang mengembalikan false akan membatalkan penyimpanan. Ini bisa membingungkan karena tidak ada error yang jelas. Sebaiknya gunakan throw :abort di before_save atau before_create untuk membatalkan dengan cara yang lebih terprediksi.
3. Callback Terlalu Gemuk
Menaruh terlalu banyak logika di callback membuat model sulit diuji dan dipahami. Pindahkan logika yang tidak berhubungan langsung dengan siklus hidup model ke service object atau form object.
4. Callback Tidak Berjalan pada Operasi Massal
Method seperti update_all atau delete_all tidak memicu callback. Jika kamu mengandalkan callback untuk memperbarui data terkait, gunakan method yang memicu callback atau jalankan secara manual.
Alternatif Callback: Kapan Beralih?
Jika callback mulai terasa rumit, pertimbangkan alternatif berikut:
- Service object: untuk logika bisnis yang melibatkan beberapa model.
- Form object: untuk validasi dan penyimpanan data dari form yang kompleks.
- Observer: meskipun sudah tidak disarankan di Rails modern, observer bisa memisahkan callback dari model.
Pakai callback untuk hal-hal sederhana dan biarkan objek lain menangani proses yang lebih besar.
Contoh Penerapan Callback yang Tepat
Berikut contoh penggunaan callback untuk mengisi slug secara otomatis:
class Post < ApplicationRecord
before_validation :generate_slug
private
def generate_slug
self.slug = title.to_s.parameterize if title.present?
end
end
Callback ini hanya mengubah atribut pada objek itu sendiri dan tidak melibatkan model lain, jadi aman dipakai.
Untuk operasi yang lebih kompleks, misalnya mengirim notifikasi ke banyak pengguna setelah postingan dibuat, gunakan after_commit dan panggil service object. Dengan begitu, eksekusi tidak terjadi di tengah transaksi yang bisa berantakan jika terjadi rollback.
Jika callback tidak berjalan sesuai harapan, ada baiknya membaca tips debug Ruby on Rails untuk pemula yang membahas cara melacak eksekusi kode.
Saat membangun form yang kompleks, kamu mungkin perlu mengirim data ke database dengan cara yang aman. Teknik validasi form juga penting, seperti yang dijelaskan dalam cara mengirim data form ke database dengan PHP dan validasi, meskipun konteksnya berbeda, prinsip validasi tetap relevan.
Untuk tampilan antarmuka, animasi bisa meningkatkan pengalaman pengguna. Jika kamu menggunakan jQuery, ada panduan memilih metode animasi jQuery: animate, fade, atau slide yang bisa membantu memilih efek yang sesuai.
Setelah aplikasi Rails-mu siap, lakukan deploy ke VPS dengan benar agar callback dan fitur lain berjalan lancar di lingkungan produksi.
Ringkasan
Callback di Ruby on Rails menjalankan kode pada momen tertentu dalam siklus hidup model. Gunakan untuk logika sederhana yang selalu ingin dijalankan, dan beralih ke pattern lain ketika logika mulai kompleks. Pahami urutan eksekusi dan jebakan umum agar aplikasi tetap mudah dirawat.
Pertanyaan yang Sering Diajukan
Apa perbedaan before_save dan before_create?
before_save dijalankan sebelum setiap penyimpanan, baik create maupun update. before_create hanya dijalankan saat objek baru pertama kali disimpan.
Bagaimana cara membatalkan penyimpanan di dalam callback?
Di Rails 5 dan versi setelahnya, gunakan throw :abort di dalam callback before_save atau before_create. Mengembalikan false tidak lagi direkomendasikan.
Apakah callback bisa menyebabkan masalah performa?
Bisa, terutama jika callback memicu query tambahan atau memanggil service yang berat. Sebaiknya gunakan callback untuk operasi ringan dan pertimbangkan background job untuk tugas berat.
