Laravel Pruning

    Tutorial Laravel Pruning: Menjaga Database Anda Tetap Ringan dan Efisien

    Bosan dengan kekacauan data yang tak terkelola di database Anda? Laravel Pruning adalah solusi yang Anda cari! Pelajari cara mengautomasi proses pemangkasan data yang tidak lagi diperlukan dengan panduan lengkap ini.

    Irsyad A. Panjaitan

    8 min read·18 Aug 2023

    Laravel Pruning

    Intro

    Laravel Pruning adalah fitur yang memungkinkan kita untuk secara berkala menghapus data yang tidak lagi dibutuhkan. Fitur ini berguna untuk menjaga database tetap ringkas dan efisien. Dalam artikel ini, kita akan memahami cara menggunakan Prunable dan MassPrunable untuk melakukannya.

    FAQ

    Apa Itu Pruning?

    Pruning dalam konteks Laravel berarti proses penghapusan data yang sudah tidak diperlukan lagi dari database. Ini dapat melibatkan penghapusan data/record yang sudah kadaluarsa, tidak valid, atau memenuhi kondisi tertentu yang ditetapkan oleh pengembang.

    Mengapa Pruning Penting?

    Seiring waktu, database dapat tumbuh dengan data yang sudah tidak diperlukan lagi. Hal ini dapat mengurangi kinerja dan efisiensi aplikasi. Pruning membantu dalam menghapus data ini, menjaga ukuran database tetap terkendali.

    Laravel Trait

    Laravel menyediakan dua trait khusus untuk mendukung pruning:

    • Prunable: Dengan trait ini, Anda dapat menentukan query kustom untuk menentukan model mana yang harus dipangkas. Anda juga dapat mendefinisikan metode pruning untuk menangani logika tambahan sebelum model dihapus.
    • MassPrunable: Trait ini memungkinkan penghapusan massal, yang lebih efisien tetapi tidak memicu model. Hal ini bisa digunakan ketika Anda perlu menghapus banyak record sekaligus.

    Contoh Nyata

    Mari kita buat contoh nyata untuk Laravel Pruning dengan skenario menghapus pengguna yang belum diverifikasi dalam 7 hari terakhir. Ini akan menggunakan field email_verified_at dalam model User.

    User Factory

    Karena Laravel sendiri telah memberikan kita UserFactory by default, maka kita bisa menggunakannya untuk membuat dummy data.

    Pertama sekali, silakan buka terminal Anda untuk membuat user seeder seperti:

    Terminal
    php artisan make:seeder UserSeeder
    

    Setelah itu, silakan buka file nya dan modifikasi seperti berikut ini:

    database/seeders/UserSeeder.php
    use App\Models\User;
    
    public function run(): void
    {
        User::factory()->count(10)->create([
            'created_at' => now()->subWeeks(rand(3,5)),
        ]);
    
        User::factory()->unverified()->count(10)->create([
            'created_at' => now()->subWeeks(rand(3,5)),
        ]);
    }
    

    Setelah itu, silakan buka kembali terminal Anda dan jalankan perintah berikut:

    Terminal
    php artisan db:seed --class=UserSeeder
    

    Dengan begitu, maka sekarang kita akan mempuyai 20 user yang mana 10 sudah verifikasi dan 10 nya lagi belum. Ingat, bahwa verifikasi di sini akan dipicu dari field email_verified_at yang ada pada migrasi users.

    Menambahkan Trait

    Karena kita sedang bekerja dengan user, maka kita perlu menambahkan 1 trait kepada modelnya dengan nama Prunable seperti berikut:

    app/Models/User.php
    + use Illuminate\Database\Eloquent\Prunable;
    
    class User extends Authenticatable
    {
    +    use Prunable;
         use HasApiTokens;
         use HasFactory;
         use Notifiable;
    

    Maka sekarang kita bisa menambahkan method prunable tepat pada model ini juga.

    app/Models/User.php
    use Illuminate\Database\Eloquent\Builder;
    use Illuminate\Database\Eloquent\Prunable;
    
    class User extends Model
    {
        use Prunable;
    
        /**
         * Get the prunable model query.
         */
        public function prunable(): Builder
        {
            return static::whereNull('email_verified_at')
                         ->where('created_at', '<=', now()->subDays(7));
        }
    }
    

    Testing

    Setelah semua di lakukan, maka sekarang Anda bisa langsung membuka terminal dan jalankan perintah:

    Terminal
    php artisan model:prune --pretend
    

    Perintah di atas akan memberikan output berapa jumlah data yang perlu dipangkas seperti:

    Terminal
    INFO  10 [App\Models\User] records will be pruned.
    

    Dan jika kita ingin menjalankan prune nya, maka silakan hilangkan --pretend seperti:

    Terminal
    php artisan model:prune
    

    Dengan begitu, maka semua record akan terhapus di dalam database kecuali yang sudah verifikasi.

    Terminal
    INFO  Pruning [App\Models\User] records.
    
    App\Models\User ............................10 records
    

    Soft Delete

    Laravel Pruning mempengaruhi model yang menggunakan soft delete. Jika model Anda menggunakan trait SoftDeletes dan terpenuhi kriteria yang ditetapkan dalam metode prunable, maka model tersebut akan dihapus secara permanen menggunakan metode forceDelete.

    Jadi jika model User Anda juga menggunakan trait SoftDeletes, dan Anda menerapkan Pruning pada model tersebut, pengguna yang cocok dengan kriteria pruning akan dihapus secara permanen dari database, bahkan jika mereka telah di "soft delete".

    Ini adalah hal yang perlu diperhatikan saat menggunakan pruning dengan model yang menggunakan soft delete, karena dapat mengakibatkan penghapusan data yang tidak dapat dikembalikan.

    Berikut adalah contoh bagaimana Anda mungkin ingin memodifikasi metode prunable jika Anda ingin memangkas pengguna yang belum diverifikasi dalam 7 hari terakhir dan telah masuk dalam daftar "soft delete":

    app/Models/User.php
    public function prunable(): Builder
    {
        return static::onlyTrashed()
                     ->whereNull('email_verified_at')
                     ->where('created_at', '<=', now()->subDays(7));
    }
    

    Metode onlyTrashed akan memastikan bahwa hanya pengguna yang telah di-soft delete (yaitu, mereka yang memiliki nilai non-null dalam kolom deleted_at) yang akan dipertimbangkan untuk dihapus.

    Kapan kita menggunakan MassPrunable

    MassPrunable dalam Laravel digunakan saat Anda ingin menghapus sejumlah besar model dari database secara lebih efisien dibandingkan dengan penggunaan prunable biasa. Berikut adalah beberapa situasi di mana Anda mungkin ingin menggunakan MassPrunable:

    1. Penghapusan Besar-besaran: Jika Anda memiliki jumlah besar data yang perlu dipangkas secara berkala, menggunakan MassPrunable akan memungkinkan penghapusan massal dalam satu query, daripada menghapus setiap model satu per satu.
    2. Efisiensi: MassPrunable lebih efisien karena tidak memuat model ke memori sebelum menghapusnya. Hal ini berarti bahwa metode deleting dan deleted, serta metode pruning pada model, tidak akan dipanggil. Ini memungkinkan operasi penghapusan menjadi lebih cepat.
    3. Situasi di Mana Event Tidak Diperlukan: Jika Anda tidak perlu menjalankan logika khusus sebelum atau setelah penghapusan (seperti event deleting atau deleted), MassPrunable adalah pilihan yang baik karena akan mengabaikan event-event tersebut.

    Berikut adalah contoh bagaimana Anda bisa menggunakan trait MassPrunable pada model User Anda:

    app/Models/User.php
    use Illuminate\Database\Eloquent\Builder;
    use Illuminate\Database\Eloquent\MassPrunable;
    
    class User extends Model
    {
        use MassPrunable;
    
        public function prunable(): Builder
        {
            return static::whereNull('email_verified_at')
                         ->where('created_at', '<=', now()->subDays(7));
        }
    }
    

    Peringatan

    Meskipun MassPrunable lebih efisien, perlu diingat bahwa karena model tidak dimuat sebelum penghapusan, Anda tidak dapat menjalankan logika khusus pada model sebelum penghapusan. Jadi, jika Anda perlu menjalankan kode sebelum menghapus model, Anda mungkin akan lebih memilih menggunakan Prunable biasa.

    Secara keseluruhan, penggunaan MassPrunable cocok untuk situasi di mana Anda perlu memangkas banyak data dengan cepat dan efisien, tanpa perlu menjalankan logika tambahan sebelum atau setelah penghapusan.

    Apakah prune() == pruning() ?

    Tentu tidak, karena prune() dan pruning() bukanlah metode yang sama dalam konteks Laravel Pruning.

    prune() adalah metode yang melakukan pemangkasan itu sendiri, sementara pruning() adalah metode yang Anda gunakan untuk menentukan apa yang harus terjadi sebelum model dipangkas.

    Metode pruning dalam Laravel digunakan dalam situasi di mana Anda perlu menjalankan logika khusus sebelum model dipangkas. Dengan menambahkan metode pruning ke model Anda, Anda bisa menentukan tindakan kustom yang harus diambil sebelum model tersebut dihapus dari database.

    Berikut adalah beberapa situasi di mana Anda mungkin ingin menggunakan metode pruning:

    1. Menghapus Resource Terkait: Jika model yang akan dipangkas memiliki resource terkait yang perlu dihapus, seperti file yang disimpan di penyimpanan eksternal, Anda dapat menggunakan metode pruning untuk memastikan file-file tersebut dihapus sebelum model dipangkas.
    2. Melogging Informasi: Anda mungkin ingin melogging informasi tentang model yang dipangkas, misalnya untuk keperluan audit atau pelacakan. Metode pruning memungkinkan Anda menambahkan kode untuk melogging detail yang relevan sebelum penghapusan.
    3. Pemberitahuan: Jika Anda perlu memberi tahu sistem lain atau komponen aplikasi tentang pemangkasan yang akan terjadi, Anda dapat menggunakan metode pruning untuk mengirim pemberitahuan tersebut.

    Misalkan Anda memiliki model User, dan sebelum memangkas pengguna, Anda ingin menghapus avatar yang terkait dengan pengguna tersebut dari penyimpanan. Anda bisa melakukannya dengan metode pruning:

    app/Models/User.php
    class User extends Model
    {
        use Prunable;
    
        protected function pruning(): void
        {
            Storage::delete($this->avatar_path);
        }
    
        public function prunable(): Builder
        {
            return static::where('last_active_at', '<=', now()->subYears(1));
        }
    }
    

    Dalam contoh ini, metode pruning memastikan bahwa file avatar dihapus dari penyimpanan sebelum model pengguna dipangkas.

    FYI

    Penting untuk diingat bahwa metode pruning hanya bekerja dengan trait Prunable dan tidak dengan MassPrunable, karena MassPrunable menghapus data secara massal tanpa memuat model terlebih dahulu, sehingga metode seperti pruning tidak akan dipanggil.

    Situasi-situasi seperti ini membuat metode pruning menjadi alat yang berguna saat Anda perlu mengelola aspek-aspek tambahan dari model yang akan dipangkas, selain hanya penghapusan dari database.

    Schedule

    Karena Laravel dilengkapi dengan alat penjadwalan yang fleksibel dan kuat, kita dapat dengan mudah menjadwalkan tugas-tugas berulang seperti pemangkasan data.

    Proses pemangkasan memungkinkan kita untuk membersihkan data yang tidak lagi diperlukan dari database kita, menjaga sistem tetap ringan dan efisien.

    Pertama, silakan buka file yang ada di app\Console\Kernel.php, dan silakan masukkan schedule nya seperti:

    app/Console/Kernel.php
    protected function schedule(Schedule $schedule): void
    {
        $schedule->command('model:prune')->daily();
    }
    

    Untuk melihat jadwal ini bekerja, cukup jalankan perintah berikut di terminal:

    Terminal
    php artisan schedule:work
    

    FYI

    Jika Anda tidak mengetahui banyak tentang laravel schedule, bisa langsung melihat nya disini Laravel Task Scheduling.

    Selamat mencoba, dan semoga berhasil. Saya Irsyad dan sampai jumpa di artikel selanjutnya.

    Kesimpulan

    Dengan menambahkan beberapa baris kode dalam model dan menjadwalkan tugas dengan Scheduler Laravel, kita dapat secara otomatis membersihkan data tersebut berdasarkan kriteria yang kita tentukan.

    Kita juga memiliki fleksibilitas untuk melakukan pemangkasan massal yang lebih efisien dengan MassPrunable atau menambahkan logika kustom sebelum pemangkasan dengan metode pruning().

    Laravel sekali lagi menunjukkan kekuatannya dalam menyederhanakan tugas-tugas yang rumit, memungkinkan pengembang seperti kita di parsinta untuk fokus pada hal-hal yang benar-benar penting dalam pengembangan aplikasi.

    Karteil
    Destinasi Utama Belajar Online dengan Format Tulisan yang Elegan
    Kunjungi Sekarang

    Irsyad A. Panjaitan

    Let's start living like no one can help us in any event, so that when we are helped in certain times, it becomes a plus in itself.

    Follow me on
    Support me
    SaweriaGithub

    Newsletter

    Bergabunglah dengan 23.000+ lainnya dan jangan pernah ketinggalan screencast, tips, tutorial, dan lainnya.