Laravel - Deleting Data

 

Deleting Data

Delete Model Yang Memiliki Relasi

Saat ini kita memiliki table relation antara blog_posts dan comments, seperti dibawah ini

Jika kita menghapus comment lewat Comment Model, tidak akan terjadi masalah. Tapi apabila kita menghapus blog_posts yang memiliki comments, maka akan terjadi masalah Sekarang coba hapus salah satu blog_post yang memiliki comments, maka hasilnya menjadi menjadi error.

Error ini terjadi karena ada constraint FK blog_post_id di tabel comments.

Delete Related Table Menggunakan Laravel Model Event

Untuk meng-handle masalah tersebut kita akan menggunakan Laravel Model Event Buka file app/Models/BlogPost.php dan tambahkan code dibawah ini.

<?php

 

namespace App\Models;

 

use Illuminate\Database\Eloquent\Factories\HasFactory;

use Illuminate\Database\Eloquent\Model;

 

class BlogPost extends Model

{

    protected $fillable = ['title''content'];

    use HasFactory;

 

    public function comments()

    {

        return $this->hasMany(Comments::class);

    }

 

    protected static function booted()

    {

        static::deleting(function (BlogPost $post){

            $post->comments()->delete();

        });

    }

}

Sekarang coba hapus salah satu blog_post yang memiliki comments, maka hasilnya menjadi seperti dibawah ini.


Refrensi : Eloquent Event

 

Delete Related Table Menggunakan Database Cascading

Cara lain untuk meng-handle masalah tersebut adalah dengan menggunakan cascade pada database level. Buat migration baru

php artisan make:migration AddCascadeDeleteToCommentsTable

Buka file database/migrations/yyyy_mm_dd_time_add_cascade_delete_to_comments_tabl e.php dan ubah menjadi menjadi seperti ini.

<?php

 

use Illuminate\Database\Migrations\Migration;

use Illuminate\Database\Schema\Blueprint;

use Illuminate\Support\Facades\Schema;

 

class AddCascadeDeleteToCommentsTable extends Migration

{

    /**

     * Run the migrations.

     *

     * @return void

     */

    public function up()

    {

        Schema::table('comments'function (Blueprint $table) {

            $table->dropForeign(['blog_post_id']);

            $table->foreign('blog_post_id')

                ->references('id')

                ->on('blog_posts')

                ->onDelete('cascade');

        });

    }

 

    /**

     * Reverse the migrations.

     *

     * @return void

     */

    public function down()

    {

        Schema::table('comments'function (Blueprint $table) {

            $table->dropForeign(['blog_post_id']);

            $table->foreign('blog_post_id')

                ->references('id')

                ->on('blog_posts');

        });

    }

}

Jalan migration

php artisan migrate

Buka file app/Models/BlogPost.php dan tambahkan code dibawah ini

<?php

 

namespace App\Models;

 

use Illuminate\Database\Eloquent\Factories\HasFactory;

use Illuminate\Database\Eloquent\Model;

 

class BlogPost extends Model

{

    protected $fillable = ['title''content'];

    use HasFactory;

 

    public function comments()

    {

        return $this->hasMany(Comments::class);

    }

 

    protected static function booted()

    {

        // static::deleting(function (BlogPost $post){

        //     $post->comments()->delete();

        // });

    }

}

 

 

Sekarang coba hapus salah satu blog_post yang memiliki comments, maka hasilnya menjadi seperti dibawah ini.


 

Model Soft Deleting

Pada real world applications kadang kita membutuhkan kehati-hatian dalam dalam melakukan delete data. Sebagai contoh di website berbasis Wordpress, ketika kita mendelete blog post, maka secara default blog post tersebut akan masuk ke Trash. Data tersebut masih ada di database dan bisa kita restore. Mekanisme delete seperti ini disebut dengan Soft Delete.

Implementasi Soft Delete pada Laravel cukup sederhana. Ketika mend-delete data, Laravel tidak mendelete nya dari database, tapi memberikan flag delete pada column delete_at. Apabila column delete_at ada isinya, maka itu tanda rows tersebut statusnya sudah deleted

Buat migration baru

php artisan make:migration AddSoftDeleteToBlogPostsTable

Buka file database/migrations/yyyy_mm_dd_time_add_soft_delete_to_blog_posts_table.p hp dan ubah menjadi menjadi seperti ini.

<?php

 

use Illuminate\Database\Migrations\Migration;

use Illuminate\Database\Schema\Blueprint;

use Illuminate\Support\Facades\Schema;

 

class AddSoftDeleteToBlogPostsTable extends Migration

{

    /**

     * Run the migrations.

     *

     * @return void

     */

    public function up()

    {

        Schema::table('blog_posts'function (Blueprint $table) {

            $table->softDeletes();

        });

    }

 

    /**

     * Reverse the migrations.

     *

     * @return void

     */

    public function down()

    {

        Schema::table('blog_posts'function (Blueprint $table) {

            $table->dropSoftDeletes();

        });

    }

}

 

Buka file app/Models/BlogPost.php dan tambahkan code dibawah ini.

<?php

 

namespace App\Models;

 

use Illuminate\Database\Eloquent\Factories\HasFactory;

use Illuminate\Database\Eloquent\Model;

use Illuminate\Database\Eloquent\SoftDeletes;

 

class BlogPost extends Model

{

    use SoftDeletes;

    protected $fillable = ['title''content'];

    use HasFactory;

 

    public function comments()

    {

        return $this->hasMany(Comments::class);

    }

 

    protected static function booted()

    {

        // static::deleting(function (BlogPost $post){

        //     $post->comments()->delete();

        // });

    }

}

Sekarang coba hapus salah satu atau beberapa blog_post, kemudian lihat di database nya, maka rows yang di delete pada column deleted_at akan terisis timestamps ketika delete.

Query Soft Deleted Rows

Silahkan masuk ke tinker

 php artisan tinker

Sekarang kita coba menggunakan method all() untuk get data dari tabel lewat model. Method ini akan me-return semua column dan semua rows yang deleted_at nya NULL


Karena kita sedang memastikan soft deleted rows, untuk sementera kita perlu menyederhanakanya hanya mereturn id column saja. Untuk implementasinya kita akan menggunakan method pluck().


Untuk me-return semua data (include soft deleted rows) kita bisa menggunakan method withTrashed(). Kita lihat id 4 saat ini muncul, sedangkan di query sebelumnya tidak muncul.

Untuk me-return data soft deleted rows saja, kita bisa menggunakan method onlyTrashed(). Kita lihat hanya id 4 yang saat ini muncul.


Untuk mengecek apakah row sudah deleted atau belum kita bisa menggunakan method trashed(). Sekarang kita coba query data yang belum di delete.

$post = BlogPost::find(id);

Kemudian kita check apakah sudah deleted atau belum dengan menggunakan method trashed(). Kalau return false, berarti data tersebut belum di delete, kalau return nya true, berarti data tersebut sudah di delete.

 $post->trashed();



Restore Soft Deleted Rows

Untuk me-restore soft deleted rows, kita akan menggunakan method restore(). Masuk ke tinker dan Cari salah satu BlogPost yang sudah di delete, kemudian di restore.

Cari BlogPost → $post = BlogPost::onlyTrashed()->get()->first();

Cek apakah trashed: → $post->trashed(); → harusnya true

Restore BlogPost → $post->restore();

Cek apakah trashed: → $post->trashed(); → harusnya false

Soft Deleted dan Restoring Relation Model

Saat ini kita baru implementasi soft delete pada model BlogPost. Sebagaimana yang kita tahu, BlogPost model memiliki relation ke Comment model. Oleh karena itu ketika kita delete BlogPost, maka kita juga harus delete Comment. Dan kita akan menggunakan soft delete.

Buat migration baru

php artisan make:migration AddSoftDeleteToCommentsTable

buka file

database/migrations/ yyyy_mm_dd_time_add_soft_delete_to_comments_table.ph p dan ubah menjadi menjadi seperti ini

<?php

 

use Illuminate\Database\Migrations\Migration;

use Illuminate\Database\Schema\Blueprint;

use Illuminate\Support\Facades\Schema;

 

class AddSoftDeleteToCommentsTable extends Migration

{

    /**

     * Run the migrations.

     *

     * @return void

     */

    public function up()

    {

        Schema::table('comments'function (Blueprint $table) {

            $table->softDeletes();

        });

    }

 

    /**

     * Reverse the migrations.

     *

     * @return void

     */

    public function down()

    {

        Schema::table('comments'function (Blueprint $table) {

            $table->dropSoftDeletes();

        });

    }

}

 

Jalan migration

php artisan migrate

Buka file app/Models/Comment.php dan tambahkan code dibawah ini.

<?php

 

namespace App\Models;

 

use Illuminate\Database\Eloquent\Factories\HasFactory;

use Illuminate\Database\Eloquent\Model;

use Illuminate\Database\Eloquent\SoftDeletes;

 

class Comments extends Model

{

    use SoftDeletes;

    use HasFactory;

 

    protected $table = 'comments';

    protected $fillable = ['content''blog_post_id'];

 

    public function post()

    {

        return $this->belongsTo(BlogPost::class);

    }

}

Buka file app/Models/BlogPost.php dan tambahkan code dibawah ini.

<?php

 

namespace App\Models;

 

use Illuminate\Database\Eloquent\Factories\HasFactory;

use Illuminate\Database\Eloquent\Model;

use Illuminate\Database\Eloquent\SoftDeletes;

 

class BlogPost extends Model

{

    use SoftDeletes;

    protected $fillable = ['title''content'];

    use HasFactory;

 

    public function comments()

    {

        return $this->hasMany(Comments::class);

    }

 

    protected static function booted()

    {

        static::deleting(function (BlogPost $post){

            $post->comments()->delete();

        });

 

        static::restoring(function (BlogPost $post){

            $post->comments()->restore();

        });

    }

}

 

 

Masuk ke tinker                

Cari satu BlogPost yang memiliki comments.

a. Cari BlogPost → $post = BlogPost::has('comments')->get()->first();

 b. Delete BlogPost → $post->delete();

c. Check apakah sudah deleted → $post->trashed();


Dalam kasus ini, id BlogPost nya adalah 7. Sekarang kita lihat data di table blog_posts dan dengan id = 7 dan data di table comments dengan blog_post_id = 7, column deleted_at nya sudah ada timestamp nya

Table blog_posts

Table comments

Sekarang kita coba restore BlogPost dengan id = 7

Sekarang kita lihat data di table blog_posts dan dengan id = 7 dan data di table comments dengan blog_post_id = 7, column deleted_at nya sudah jadi NULL

Table blog_posts


Table comments



 

Next Post Previous Post
No Comment
Add Comment
comment url