
Pendahuluan
Bayangin lagi ngerjain fitur sederhana, tapi tiba-tiba requirement-nya nambah: user harus bisa kasih like ke postingan, komentar, bahkan foto profil. Kalau bikin tabel like terpisah buat tiap model, database bakal penuh sama tabel yang isinya cuma itu-itu aja. Saya pernah di posisi itu, bikin 3 tabel buat like dan akhirnya malah pusing sendiri pas mau maintenance. Di sinilah Polymorphic Relation di Laravel jadi penyelamat hidup kita.
Tips & Best Practices
Di banyak project, biasanya saya mulai dari bikin satu model Like yang punya polymorphic relation, supaya nggak perlu bikin tabel baru tiap kali ada fitur yang butuh sistem rating.
Seringkali saya simpan state like/dislike sebagai integer (1 untuk like, -1 untuk dislike) daripada string, karena ini bakal bikin proses agregasi atau penjumlahan total poin jauh lebih enteng di database.
Pas performa mulai jadi concern, saya selalu pastikan buat pasang index di kolom polymorphic-nya, soalnya pencarian record berdasarkan 'id' dan 'type' bakal melambat kalau tabelnya sudah jutaan baris.
Contoh Kode
Kita setup model Like-nya biar fleksibel. Saya biasanya buat migration seperti ini:
Schema::create('likes', function (Blueprint $table) {
$table->id();
$table->morphs('likeable'); // Ini bakal bikin likeable_id dan likeable_type
$table->foreignId('user_id');
$table->tinyInteger('value'); // 1 atau -1
$table->timestamps();
});Lalu di model Post atau Comment, tinggal tambahkan trait relation-nya:
public function likes() {
return $this->morphMany(Like::class, 'likeable');
}Variasi Implementasi
Ada dua pendekatan yang sering saya pakai. Pertama, pakai Polymorphic langsung (seperti di atas) karena simpel dan hemat tabel. Kedua, pakai pendekatan Counter Cache, yaitu nyimpen total like di kolom 'likes_count' di tabel utamanya. Kalau traffic-nya tinggi banget, mendingan pakai Counter Cache supaya query COUNT(*) nggak bikin database megap-megap setiap kali page loading.
Kesalahan Umum
- Lupa hapus record terkait saat model induk dihapus (solusinya harus pakai
onDelete('cascade')di migration). - Kebiasaan query
->count()di dalam loop blade (ini bikin N+1 problem yang parah). - Gak validasi input 1/-1, jadinya data masuk aneh-aneh.
- Nggak pakai database index, alhasil query jadi lambat saat user udah ribuan.
- Mencampuradukkan logic like dengan sistem notifikasi, sebaiknya pisah lewat observer atau event.
Ringkasan
Akhirnya, kunci dari fitur ini bukan cuma di kodenya, tapi di gimana kita ngebayangin skala datanya nanti. Laravel udah kasih kemudahan lewat polymorphic, jadi manfaatkan itu buat bikin code yang bersih. Pas saya refactor project terakhir, fitur ini jadi jauh lebih rapi dibanding pas awal saya 'paksa' pakai tabel terpisah.
Komentar
Posting Komentar