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