Site icon agussuratna.net

Tutorial Laravel #14 : Soft Deletes

Soft Deletes adalah fitur dari laravel untuk membuat penghapusan data sementara, kita bisa menghapus data pada table tapi data tersebut tidak benar-benar langsung dihapus, masih tersimpan dalam table tapi tidak tampil lagi.

Ibaratnya ketika kita menghapus sebuah data disana, sebenarnya data tersebut tidak benar-benar terhapus, contoh paling mudah adalah ketika kita menghapus file di komputer maka data tersebut tidak benar-benar hilang dari komputer kita, tapi pindah ke Recycle Bin (Windows) atau Trash (Linux dan macOS). Karena data-nya masih tersimpan, maka nantinya kita bisa mengembalikan (Restore) file tersebut atau kita juga bisa menghapus data tersebut secara permanen.

Kurang lebih seperti itu, di laravel kita tidak perlu susah-susah untuk membuat fitur semacam ini pada aplikasi kita. Laravel sudah menyediakan fitur SoftDeletes yang bisa langsung kita gunakan.

 

Cara Menggunakan Soft Deletes

Untuk mulai belajar tentang Soft Deletes, pastikan kita sudah memiliki sebuah database dan table yang akan kita olah. Untuk contoh saya sudah membuat database dengan nama ‘datasekolah‘ dan table dengan nama ‘guru‘.

Jika belum ada dataabse dan tabelnya, silahkan buat dulu database dan tablenya, dan isi beberapa data percobaan. Untuk cara membuat tablenya dan mengisi datanya kita bisa buat dan isi dengan cara manual di phpmyadmin atau bisa menggunakan migration dan menginput data dummy dengan Seeding & Faker seperti yang sudah kita pelajari pada tutorial sebelumnya. Skema table guru yang kita butuhkan adalah kolum id, nama, umur, created_at dan updated_at. Atau jika kita ingin cepat, kita bisa mengimport sql berikut ke database ‘datasekolah’.

guru.sql

-- phpMyAdmin SQL Dump
-- version 5.0.2
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1
-- Waktu pembuatan: 21 Apr 2021 pada 18.07
-- Versi server: 10.4.13-MariaDB
-- Versi PHP: 7.4.8

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

--
-- Database: `datasekolah`
--

-- --------------------------------------------------------

--
-- Struktur dari tabel `guru`
--

CREATE TABLE `guru` (
  `id` int(10) UNSIGNED NOT NULL,
  `nip` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `nama` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `alamat` text COLLATE utf8mb4_unicode_ci NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  `deleted_at` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

--
-- Dumping data untuk tabel `guru`
--

INSERT INTO `guru` (`id`, `nip`, `nama`, `alamat`, `created_at`, `updated_at`, `deleted_at`) VALUES
(4, '0', 'Uchita Mardhiyah', 'Dk. Mulyadi No. 184, Pasuruan 94641, Sumbar', NULL, NULL, NULL),
(5, '8', 'Latif Ardianto', 'Ds. Laswi No. 890, Sorong 70207, Jabar', NULL, NULL, NULL),
(6, '9', 'Estiono Thamrin', 'Gg. Dago No. 161, Jayapura 96901, Papua', NULL, NULL, NULL),
(7, '9', 'Ihsan Pradipta', 'Kpg. Flores No. 844, Binjai 53465, Sulbar', NULL, NULL, NULL),
(8, '7', 'Daliman Prabu Manullang S.Psi', 'Ki. Siliwangi No. 692, Tasikmalaya 34889, Babel', NULL, NULL, NULL),
(9, '8', 'Harsanto Ardianto', 'Psr. Babah No. 975, Administrasi Jakarta Pusat 94428, Sumbar', NULL, NULL, NULL),
(10, '5', 'Radika Gunawan', 'Kpg. Ketandan No. 132, Administrasi Jakarta Utara 91117, Kalbar', NULL, NULL, NULL),
(11, '7', 'Cagak Pradipta', 'Gg. Wora Wari No. 848, Probolinggo 31584, Sumsel', NULL, NULL, NULL),
(12, '4', 'Margana Marsudi Pradana M.Ak', 'Ds. Gajah Mada No. 607, Depok 65847, Malut', NULL, NULL, NULL),
(13, '5', 'Emas Prasetyo M.Ak', 'Ds. Kartini No. 585, Magelang 70896, Kaltara', NULL, NULL, NULL);

--
-- Indexes for dumped tables
--

--
-- Indeks untuk tabel `guru`
--
ALTER TABLE `guru`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT untuk tabel yang dibuang
--

--
-- AUTO_INCREMENT untuk tabel `guru`
--
ALTER TABLE `guru`
  MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=14;
COMMIT;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

Intinya kita mempunyai tabel guru dengan struktur table seperti di atas, untuk menggunakan fitur Soft Deleting kita wajib memiliki kolum deleted_at , maka kita bisa buat secara manual dengan menambahkan kolum baru di table guru melalui phpmyadmin, tambahkan 1 kolom pada table guru dengan nama “deleted_at“ dengan tipe data datetime dan DEFAULT NULL.

Koneksi Database

Sebelum lanjut ke tahap soft delets, kita konfigurasi dulu databasenya pada file .env pada project laravel kita. Pada project laravel yang digunakan untuk tutorial ini sya gunakan project dengan nama ‘latihan_laravel‘. Jika belum ada projectnya silahkan buat dahulu, cara membuat projectnya silahkan baca di https://agussuratna.net/2020/11/27/cara-install-laravel-8-di-windows/

.env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=datasekolah
DB_USERNAME=root
DB_PASSWORD=root

 

Menampilkan Data

Untuk menampilkan data dengan Eloquent Laravel sudah kita pelajari pada tutorial laravel sebelumnya, bisa di bawa di https://agussuratna.net/2021/04/18/tutorial-laravel-8-crud-laravel-menggunakan-eloquent/ .

Sekarang kita buat route untuk dulu menampilkan data guru.

latihan_laravel/routes/web.php

Route::get('/guru', 'GuruController@index');

Route ‘/guru’ yang kita buat di atas, akan menjalankan method index() yang ada dalam controller GuruController. Jika kita belum punya controller GuruController.php, maka sekarang kita buat dulu controller GuruController.php menggunakan php artisan dengan cara masuk ke direktori project laravel melalui terminal atau CMD dan buat controller dengan php artisan.

php artisan make:controller GuruController

Kemudian buat fungsi/method index() pada controller GuruController.php.

latihan_laravel/app/Http/controllers/GuruController.php

<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;

// panggil model guru
use App\Models\Guru;

class GuruController extends Controller
{
    // menampilkan data guru
    public function index()
    {
        $guru = Guru::All();
        return view('guru', ['guru' => $guru]);
    }
}

Perhatikan pada controller di atas, kita memanggil model Guru.php, karena kita akan menampilkan data dari table guru.

use App\Models\Guru;

Selanjutnya kita ambil data dari table guru dengan fungsi all() dan kita passing ke view guru.blade.php.

// menampilkan data guru
public function index()
{
    $guru = Guru::All();
    return view('guru', ['guru' => $guru]);
}

Karena kita belum mempunyai model Guru.php dan view guru.blade.php, maka akan kita buat kedua file tersebut. Kita buat model dengan Guru.php menggunakan php artisan :

php artisan make:model Guru

Pada model Guru.php, kita deklarasikan dulu bahwa kita akan menggunakan table dengan nama ‘guru‘, bukan ‘gurus’ (plural model eloquent), dengan sintak protected $table = “guru”; .

latihan_laravel/app/Models/Guru.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Guru extends Model
{
    use HasFactory;
    protected $table = "guru";
}

Selanjutnya karena pada controller data gurunya kita passing ke view guru.blade.php, maka kita buat sebuah file view baru dengan nama guru.blade.php.

latihan_laravel/resources/views/guru.blade.php

<!DOCTYPE html>
<html>
    <head>
        <title>Tutorial Laravel : Soft Deletes </title>
            <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
    </head>

    <body>
        <div class="container">
            <div class="card mt-5">
                <div class="card-header text-center">
                    Data guru
                </div>
                
                <div class="card-body">
                    <a href="/guru" class="btn btn-sm btn-primary">Data Guru</a>
                    |
                    <a href="/guru/trash">Buang ke Tempat Sampah</a>
                    <br/>
                    <br/>
                    
                    <table class="table table-bordered">
                        <thead>
                            <tr>
                                <th>NIP</th>
                                <th>Nama</th>
                                <th>Alamat</th>
                                <th width="1%">OPSI</th>
                            </tr>
                        </thead>

                        <tbody>
                            @foreach($guru as $g)
                                <tr>
                                    <td>{{ $g->nip }}</td>
                                    <td>{{ $g->nama }}</td>
                                    <td>{{ $g->alamat }}</td>
                                    <td><a href="/guru/hapus/{{ $g->id }}" class="btn btn-danger btn-sm">Hapus</a></td>
                                </tr>
                            @endforeach
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </body>
</html>

Selanjutnya kita jalankan projectnya dengan cara di cmd/terminal ketikan :

php artisan serve

Kita lihat hasilnya dengan cara akses ke localhost:8000/guru, maka hasilnya seperti berikut :

Data guru sudah berhasil tampil, pada view guru membuat tombol hapus untuk menghapus sementara data guru dan akan dimasukkan ke folder atau tempat sampah ibaratnya.

Kemudian kita juga membuat menu tempat sampah pada bagian atas, pada saat menu tempat sampah diklik maka akan dialihkan ke halaman yang menampilkan data-data guru yang dihapus sementara. Pada halaman tempat sampah itu nanti akan kita buat juga tombol untuk menghapus data guru secara permanen atau mengembalikan (restore) dan menampilkan kembali data yang sudah dihapus tersebut.

 

Membuat Soft Deletes untuk Menghapus Sementara

Perhatikan pada tombol hapus yang kita buat pada view guru.blade.php :

<a href="/guru/hapus/{{ $g->id }}" class="btn btn-danger btn-sm">Hapus</a>

Pada saat diklik kita alihkan ke route ‘/guru/hapus/{id}’, maka kita buat route tersebut untuk meng-handle proses penghapusan data.

latihan_laravel/routes/web.php

Route::get('/guru/hapus/{id}', 'GuruController@hapus');

Route ini akan menghandle proses penghapusan kita arahkan ke method hapus() dalam controller GuruController.php, sambil mengirimkan id guru yang akan dihapus. Selanjutnya kita buat method hapus() pada controller GuruController.php .

latihan_laravel/app/Http/controllers/GuruController.php

// hapus sementara
public function hapus($id)
{
    $guru = Guru::find($id);
    $guru->delete();
    
    return redirect('/guru');
}

Proses penghapusan data pada method hapus() di atas masih sama seperti yang sudah kita pelajari sebelumnya yaitu menggunakan fungsi delete(); . Karena di sini kita akan menggunakan Fitur Soft Delete, maka perlu beberapa pengaturan pada model Guru.php. Buka file model Guru.php dan sesuaikan seperti berikut :

latihan_laravel/app/Models/Guru.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Guru extends Model
{
    use SoftDeletes;

    use HasFactory;
    protected $table = "guru";
    
    protected $dates = ['deleted_at'];
}

Karena kita akan menggunakan fitur SoftDeletes, maka kita harus memanggilnya terlebih dulu pada model.

use Illuminate\Database\Eloquent\SoftDeletes;

Kemudian di dalam class kita deklarasikan variabel protected $dates.

protected $dates = ['deleted_at'];

Sekarang kita coba klik tombol hapus pada salah satu data guru, setelah klik hapus maka data guru tersebut akan hilang dan tidak terlihat lagi, tapi pada database data tersebut masih ada.

Data guru yang sudah kita hapus tadi tidak terlihat lagi, tapi pada database masih ada. Pada kolum deleted_at record data yang dihapus tadi terisi dengan waktu kapan data tersebut dihapus.

Sampai disini kita telah berhasil membuat penghapusan data sementara. dimana data yang kita hapus tadi ibaratnya seperti kita masukkan ke tempat sampah.

Pada contoh di atas saya menghapus data guru yang bernama Latif Ardianto, setelah tombol Hapus diklik data di tampilan view guru.blade.php, tetapi di phpmyadmin masih ada dan kolom delete_at jadi terisi. Ini artinya soft deletes yang dibuat berhasil.

 

Menampilkan Data yang Dihapus (Isi tempat sampah)

Pada halaman view guru.blade.php kita telah membuat menu Tempat Sampah. pada menu ini nantinya akan menampilkan halaman yang menampilkan data-data yang sudah dihapus (tempat sampah).

<a href="/guru/trash">Tempat Sampah</a>

Pada saat menu/link Tempat Sampah diklik, maka akan dialihkan ke route ‘/guru/trash’. Selanjutnya kita buat route baru, yaitu route ‘/guru/trash’.

latihan_laravel/routes/web.php

Route::get('/guru/trash', 'GuruController@trash');

Route ini akan menjalankan method trash() pada controller GuruController.php, selanjutnya buat method trash() pada controller GuruController.php.

latihan_laravel/app/Http/controllers/GuruController.php

// menampilkan data guru yang sudah dihapus
public function trash()
{
    $guru = Guru::onlyTrashed()->get();
    return view('guru_trash', ['guru' => $guru]);
}

Untuk penamaan methodnya bebas, kita bisa menyesuaikan sendiri misal trash() diganti dengan sampah(), pada method trash() ini kita ambil data guru yang sudah dihapus dengan menggunakan fungsi Guru::onlyTrashed()->get(); , kemudian tinggal kita passing ke view guru_trash.blade.php. Selanjutnya kita buat view baru dengan nama guru_trash.blade.php .

latihan_laravel/resources/views/guru_trash.blade.php

<!DOCTYPE html>
<html>
    <head>
        <title>Tutorial Laravel : Soft Deletes Laravel</title>
            <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
    </head>
    
    <body>
        <div class="container">
            <div class="card mt-5">
                <div class="card-header text-center">
                    Data Guru
                </div>
                
                <div class="card-body">
                    <a href="/guru">Data Guru</a>
                    |
                    <a href="/guru/trash" class="btn btn-sm btn-primary">Tempat Sampah</a>
                    <br/>
                    <br/>
                    <a href="/guru/kembalikan_semua">Kembalikan Semua</a>
                    |
                    <a href="/guru/hapus_permanen_semua">Hapus Permanen Semua</a>
                    <br/>
                    <br/>
                    
                    <table class="table table-bordered">
                        <thead>
                            <tr>
                                <th>NIP</th>
                                <th>Nama</th>
                                <th>Alamat</th>
                                <th width="30%">OPSI</th>
                            </tr>
                        </thead>
                        
                        <tbody>
                            @foreach($guru as $g)
                                <tr>
                                    <td>{{ $g->nip }}</td>
                                    <td>{{ $g->nama }}</td>
                                    <td>{{ $g->alamat }}</td>
                                    <td>
                                        <a href="/guru/kembalikan/{{ $g->id }}" class="btn btn-success btn-sm">Restore</a>
                                        <a href="/guru/hapus_permanen/{{ $g->id }}" class="btn btn-danger btn-sm">Hapus Permanen</a>
                                    </td>
                                </tr>
                            @endforeach
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </body>
</html>

Sekarang kita lihat hasilnya, klik pada tombol Tempat Sampah atau akses url localhost:8000/guru/trash. Maka akan muncul isi tempat sampah, atau data guru-guru yang sudah kita hapus sebelumnya.

 

Restore Data yang dihapus

Pada view guru_trash.blade.php kita telah membuat sebuah tombol restore.

<a href="/guru/kembalikan/{{ $g->id }}" class="btn btn-success btn-sm">Restore</a>

Yang mengarahkan ke route ‘/guru/kembalikan/id’,  sekarang kita buat routenya dahulu

laravel_laravel/routes/web.php

Route::get('/guru/kembalikan/{id}', 'GuruController@kembalikan');

Seperti proses penghapusan data, di sini kita mengirimkan data id guru ke controller. Pada route ini kita kirimkan id guru ke method kembalikan() dalam controller GuruController.php. Kita buat method kembalikan() dalam controller GuruController.php.

latihan_laravel/app/Http/controllers/GuruController.php

// restore data guru yang dihapus
public function kembalikan($id)
{
    $guru = Guru::onlyTrashed()->where('id',$id);
    $guru->restore();
    
    return redirect('/guru/trash');
}

Pada method ini kita menangkap id guru yang ingin dikembalikan dalam parameter method kembalikan(), kemudian kita seleksi terlebih dulu data guru yang ada pada tempat sampah dan yang id nya sesuai dengan id guru yang ingin direstore, kemudian kita kembalikan/restore dengan fungsi restore().

$guru = Guru::onlyTrashed()->where('id',$id);
$guru->restore();

Kemudian kita alihkan halaman kembali ke route ‘/guru/trash’. Sekarang kita coba klik tombol restore pada data guru yang ingin di kembalikan, maka data guru tersebut akan dikembalikan (ditampilkan kembali).

Restore semua Data sang sudah sihapus sekaligus

Ketika data yang akan direstore di Tempat Sampah sangat banyak, meretore data tesebut satu-persatu tentu akan melelahkan dan menyita banyak waktu. Solusinya kita buatkan juga fitur untuk merestore semua data guru yang ada di tempat sampah.

Pada view guru_trash.blade.php kita sudah membuat link/menu untuk merestore atau mengembalikan semua data yang ada di tempat sampah.

<a href="/guru/kembalikan_semua">Kembalikan Semua</a>

Saat link ini diklik, halaman akan dialihkan ke route ‘/guru/kembalikan_semua’, sekarang kita buat route tersebut.

latihan_laravel/routes/web.php

Route::get('/guru/kembalikan_semua', 'GuruController@kembalikan_semua');

Route ini menjalankan method kembalikan_semua() pada controller GuruController.php, sekrang kita buat method tersebut :

latihan_laravel/app/Http/controllers/GuruController.php

//restore semua data guru yang sudah dihapus
public function kembalikan_semua()
{
    $guru = Guru::onlyTrashed();
    $guru->restore();
    
    return redirect('/guru/trash');
}

Perhatikan pada method tersebut, pertama kita ambil semua data yang ada di tempat sampah dan kita simpan dalam variabel $guru, kemudian kita kembalikan semua data tersebut dengan fungsi restore().

$guru = Guru::onlyTrashed();
$guru->restore();

dan terakhir kita alihkan halaman kembali ke route ‘/guru/trash’. Sekarang coba klik hapus pada beberapa data guru, kemudian masuk ke menu tempat sampah dan klik pada link kembalikan semua. Maka semua data yang ada di tempat sampah akan di restore atau kembali ditampilkan.

 

Hapus permanen Data yang dihapus

Untuk menghapus secara permanen, perhatikan pada tombol hapus permanen pada view guru_trash.blade.php.

<a href="/guru/hapus_permanen/{{ $g->id }}" class="btn btn-danger btn-sm">Hapus Permanen</a>

Tombol ini kita arahkan ke route ‘/guru/hapus_permanen/id’, sekarang buat route baru lagi.

laravel_laravel/routes/web.php

Route::get('/guru/hapus_permanen/{id}', 'GuruController@hapus_permanen');

Route ini akan menjalankan method hapus_permanen() pada controller GuruController.php sambil mengirimkan data id guru yang akan dihapus secara permanen, sekarang kita buat method hapus_permanen().

laravel_laravel/app/Http/controllers/GuruController.php

// hapus permanen
public function hapus_permanen($id)
{
    // hapus permanen data guru
    $guru = Guru::onlyTrashed()->where('id',$id);
    $guru->forceDelete();
    
    return redirect('/guru/trash');
}

Pada method hapus_permanen() ini kita tangkap data yang dikirim dari route, kemudian kita seleksi data gurunya berdasarkan id dan yang ada di tempat sampah dengan menggunakan fungsi forceDelete() untuk menghapus data tersebut secara permanan, sehinga data benar-benar dihapus dari table guru.

 

Hapus permanen semua Data yang sudah dihapus sekaligus

Untuk menghapus semua data yang ada di tempat sampah secara permanen, sama caranya seperti membuat fungsi restore untuk semua data guru, bedanya pada proses hapus permanen kita gunakan fungsi forceDelete().

Pada view guru_trash.blade.php kita sudah membuat link Hapus Permanen Semua.

<a href="/guru/hapus_permanen_semua">Hapus Permanen Semua</a>

Saat diklik kita arahkan ke route ‘/guru/hapus_permanen_semua’, sekarang kita buat routenya.

latihan_laravel/routes/web.php

Route::get('/guru/hapus_permanen_semua', 'GuruController@hapus_permanen_semua');

Route ini akan menjalankan method hapus_permanen_semua() dalam controller GuruController.php, sekarang kita buat method tersebut dalam controller GuruController.php.

latihan_laravel/app/Http/controllers/GuruController.php

// hapus permanen semua guru yang sudah dihapus
public function hapus_permanen_semua()
{
    // hapus permanen semua data guru yang sudah dihapus
    $guru = Guru::onlyTrashed();
    $guru->forceDelete();
    
    return redirect('/guru/trash');
}

Pada method hapus_permanen_semua() kita ambil semua data guru yang ada di tempat sampah, kemudian kita hapus permanen dengan fungsi forceDelete() dan terakhir kita alihkan halaman ke route ‘/guru/trash’.

Sampai di sini tutorial Soft Delete Laravel telah selesai, semoga bermanfaat.

 

Referensi :

Exit mobile version