Softdelete di Laravel (5.2)

Bagi beberapa orang keberadaan data itu cukup penting bahkan jika data itu sudah “tidak digunakan”, oleh karena itu beberapa orang tersebut jika merasa data yang ada di aplikasi tidak dibutuhkan lagi mereka tidak benar-benar menghapus data dari database tapi hanya disembunyikan saja dari tampilan di aplikasi.

Saat saya kuliah, biasanya saya mengakali hal itu dengan cara menambahkan field is_deleteddi database. Jadi, saat membuat fungsi hapus, alih-alih menghapus data saya hanya mengubah nilai is_deleted dari 0 menjadi 1. Artinya jika bernilai 1 berarti data itu “dihapus”.

Di Laravel sendiri fitur seperti itu sudah disediakan langsung di eloquent-nya, nama fiturnya adalah softdeletes.

Dalam tulisan ini saya akan mencoba mencontohkan bagaimana fitur tersebut digunakan, pertama-tama kita perlu data yang tersedia di database.

Persiapan Data

Table Migration Artikel

Pertama-tama saya buat dahulu tabel artikel yang akan digunakan untuk menampung data artikel.

php artisan make:migration create_articles_table --create=articles

Script di atas berguna untuk membuat script database migration yang akan disimpan di folder database/migration, jika sudah seharusnya akan ada berkas dengan format : tahun_bulan_tanggal_time_create_articles_table.php. Masukan Script berikut ini di berkas tersebut.

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateArticlesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->increments('id'); // primary key ID auto increment
            $table->string('title'); // field title type varchar 255
            $table->text('content'); // field content type text
            $table->timestamps(); // field created_at & updated_at type timestamp
            $table->softDeletes(); //field deleted_at type timestamp
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('articles');
    }
}

Persiapan Seeder

Tabel sudah disiapkan selanjutnya buat data dummy dengan menggunakan seeder.

php artisan make:seeder ArticleSeeder

Script di atas akan menhasilkan berkas di database/seeds dengan nama berkas ArticleSeeder.php. Isikan Script berikut di berkas tersebut.

<?php

use Illuminate\Database\Seeder;

class ArticleSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
          DB::table('articles')->insert(array(

            
             array('title'=>'Artikel 1','content'=>'Lorem ipsum artikel 1'),
             array('title'=>'Artikel 2','content'=>'Lorem ipsum artikel 2'),
             array('title'=>'Artikel 3','email'=>'Lorem ipsum artikel 3'),

          ));
    }
}

Lalu masih di lokasi yang sama pada berkas DatabaseSeeder.php pada fungsi run() ubah menjadi seperti ini :

public function run()
    {
         $this->call(ArticleSeeder::class);
    }

Terakhir eksekusi dengan perintah

php artisan migrate
php artisan db:seed

Seharusnya data sudah tersedia di database :

Persiapan Model

Buat model dengan cara :

php artisan make:model Article

Maka model baru akan muncul di folder app dengan nama Aricle.php. Isikan Script berikut di sana :

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes; //tambahkan ini untuk softdeletes

class Article extends Model
{
   use SoftDeletes;// tambahkan ini untuk fitur softdelete aktif
   protected $table = 'articles';


}

Percobaan pertama

Percobaan pertama ialah melihat data yang tersedia, seharusnya jika data dimunculkan semua akan berjumlah tiga.

<?php
$article = \App\Article::all();
dd($article);

Maka akan menghasilkan :

Collection {#303 ▼
  #items: array:3 [▼
    0 => Article {#304 ▼
      #table: "articles"
      #connection: null
      #primaryKey: "id"
      #keyType: "int"
      #perPage: 15
      +incrementing: true
      +timestamps: true
      #attributes: array:6 [▼
        "id" => 1
        "title" => "Artikel 1"
        "content" => "Lorem ipsum artikel 1"
        "created_at" => null
        "updated_at" => null
        "deleted_at" => null
      ]
      #original: array:6 [▶]
      #relations: []
      #hidden: []
      #visible: []
      #appends: []
      #fillable: []
      #guarded: array:1 [▶]
      #dates: []
      #dateFormat: null
      #casts: []
      #touches: []
      #observables: []
      #with: []
      #morphClass: null
      +exists: true
      +wasRecentlyCreated: false
      #forceDeleting: false
    }
    1 => Article {#305 ▼
      #table: "articles"
      #connection: null
      #primaryKey: "id"
      #keyType: "int"
      #perPage: 15
      +incrementing: true
      +timestamps: true
      #attributes: array:6 [▼
        "id" => 2
        "title" => "Artikel 2"
        "content" => "Lorem ipsum artikel 2"
        "created_at" => null
        "updated_at" => null
        "deleted_at" => null
      ]
      #original: array:6 [▶]
      #relations: []
      #hidden: []
      #visible: []
      #appends: []
      #fillable: []
      #guarded: array:1 [▶]
      #dates: []
      #dateFormat: null
      #casts: []
      #touches: []
      #observables: []
      #with: []
      #morphClass: null
      +exists: true
      +wasRecentlyCreated: false
      #forceDeleting: false
    }
    2 => Article {#306 ▼
      #table: "articles"
      #connection: null
      #primaryKey: "id"
      #keyType: "int"
      #perPage: 15
      +incrementing: true
      +timestamps: true
      #attributes: array:6 [▼
        "id" => 3
        "title" => "Artikel 3"
        "content" => "Lorem ipsum artikel 3"
        "created_at" => null
        "updated_at" => null
        "deleted_at" => null
      ]
      #original: array:6 [▶]
      #relations: []
      #hidden: []
      #visible: []
      #appends: []
      #fillable: []
      #guarded: array:1 [▶]
      #dates: []
      #dateFormat: null
      #casts: []
      #touches: []
      #observables: []
      #with: []
      #morphClass: null
      +exists: true
      +wasRecentlyCreated: false
      #forceDeleting: false
    }
  ]
}

Percobaan kedua, “menghapus data”

<?php
//menghapus data artikel 1
$id = 1; 
$article = \App\Article::find($id);
$article->delete();

Lalu coba cek kembali dengan fungsi yang sama dengan percobaan pertama. Maka hasilnya akan seperti berikut :

Collection {#304 ▼
  #items: array:2 [▼
    0 => Article {#305 ▼
      #table: "articles"
      #connection: null
      #primaryKey: "id"
      #keyType: "int"
      #perPage: 15
      +incrementing: true
      +timestamps: true
      #attributes: array:6 [▼
        "id" => 2
        "title" => "Artikel 2"
        "content" => "Lorem ipsum artikel 2"
        "created_at" => null
        "updated_at" => null
        "deleted_at" => null
      ]
      #original: array:6 [▶]
      #relations: []
      #hidden: []
      #visible: []
      #appends: []
      #fillable: []
      #guarded: array:1 [▶]
      #dates: []
      #dateFormat: null
      #casts: []
      #touches: []
      #observables: []
      #with: []
      #morphClass: null
      +exists: true
      +wasRecentlyCreated: false
      #forceDeleting: false
    }
    1 => Article {#306 ▼
      #table: "articles"
      #connection: null
      #primaryKey: "id"
      #keyType: "int"
      #perPage: 15
      +incrementing: true
      +timestamps: true
      #attributes: array:6 [▶]
      #original: array:6 [▶]
      #relations: []
      #hidden: []
      #visible: []
      #appends: []
      #fillable: []
      #guarded: array:1 [▶]
      #dates: []
      #dateFormat: null
      #casts: []
      #touches: []
      #observables: []
      #with: []
      #morphClass: null
      +exists: true
      +wasRecentlyCreated: false
      #forceDeleting: false
    }
  ]
}

Untuk memastikan bahwa data tidak benar-benar dihapus, buka kembali database dan lihat tabel artikel

Data artikel dengan id = 1 tetap ada namun dengan kondisi field deleted_at terisi sebuah tanggal.