DEV Community

Hilmi Hidayat
Hilmi Hidayat

Posted on • Originally published at divisidev.com on

CRUD Laravel 9 #6: Implementasi Softdelete

CRUD Laravel 9 - Setelah pada artikel sebelumnya saya telah membagikan bagaimana membuat fitur Create, Edit/Update dan Delete, maka pada artikel kali ini saya akan membagikan bagaimana cara implementasi softdelete di laravel 9. Jadi, softdelete di laravel, konsepnya sama dengan recycle bin di windows atau trash di mac os. Data yang kita hapus, sebenarnya tidak benar-benar terhapus secara permanen. Data tersebut masih tersimpan di database dan hanya berubah statusnya.

Baiklah, mari kita langsung saja ke koding 🚀

Step 1: Buat Migration

php artisan make:migration add_column_to_posts_table
Enter fullscreen mode Exit fullscreen mode

Pada step yang pertama ini, kita perlu menambahkan field baru untuk membedakan mana data yang softdelete dan yang bukan. Field baru tersebut bernama delete_at (timestamp). Silahkan jalankan perintah artisan seperti di atas untuk generate file migration yang baru.

public function up()
{
    Schema::table('posts', function (Blueprint $table) {
        $table->softDeletes();
    });
}

public function down()
{
    Schema::table('posts', function (Blueprint $table) {
        $table->dropSoftDeletes();
    });
}
Enter fullscreen mode Exit fullscreen mode

Kemudian, buka file {timestamp} _add_column_to_posts_table.php yang terdapat di direktori database/migrations dan ubah kodenya menjadi seperti di atas. Yaps, disini kita akan menambahkan softdeletes saja.

Jalankan perintah php artisan migrate untuk memigrasi file migration yang baru tersebut ke database. Sekarang, coba cek table posts, maka akan ada field baru yaitu deleted_at.

Step 2: Update Post Model

namespace App\Models;

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

class Post extends Model
{
    use HasFactory, SoftDeletes;

    protected $guarded = [];
}
Enter fullscreen mode Exit fullscreen mode

Lanjut masuk ke file Post model, disini kita perlu menambahkan trait Softdeletes dan jangan lupa juga untuk mengimportnya.

Step 3: Setup Controller

public function destroy(Post $post)
{
    $post->delete();

    return to_route('posts.index')->with('success','Post deleted successfully');
}
Enter fullscreen mode Exit fullscreen mode

Oke, sekarang kita masuk ke PostController. Sebelumnya pada method destroy, ketika data tersebut dihapus, maka file yang ada di storage juga akan dihapus. Dan sekarang, kita buat ketika data tersebut dihapus (softdeletes), file di storage belum terhapus. Maka dari itu, silahkan pergi ke PostController.php, dan sesuaikan code yang ada di method destroy seperti contoh code di atas.

public function trash()
{
    $posts = Post::onlyTrashed()->paginate(10);

    return view('posts.index',compact('posts'));
}
Enter fullscreen mode Exit fullscreen mode

Kita masih bekerja di PostController.php, dan kali ini kita perlu membuat atau menambahkan beberapa method baru. Method yang pertama adalah trash() dengan code seperti di atas. Fungsi dari method tersebut adalah menampilkan data-data dari table posts yang berstatus softdeletes atau yang mempunyai value pada field deleted_at.

public function restore($id)
{
    $post = Post::onlyTrashed()->findOrFail($id);
    $post->restore();

    return to_route('posts.index')->with('success','Post restored successfully');
}
Enter fullscreen mode Exit fullscreen mode

Kemudian method yang selanjutnya adalah restore() dengan code seperti di atas. Fungsi dari method tersebut adalah mengembalikan data dari trash (softdelete). Jadi, jika method ini dijalankan, maka data yang sebelumnya ada di trash akan dikembalikan atau direstore ke data semula.

public function delete($id)
{
    $post = Post::onlyTrashed()->findOrFail($id);

    if($post->cover){
        \Storage::delete('public/'.$post->cover);
    }

    $post->forceDelete();

    return to_route('posts.trash')->with('success','Post deleted permanently');
}
Enter fullscreen mode Exit fullscreen mode

Nah, method yang terakhir adalah delete(). Method ini difungsikan untuk menghapus data dari table secara permanen (tidak dapat direstore). Jadi, ketika method ini dipanggil maka akan menghapus file (milik data tersebut) di storage dan kemudian menghapus data tersebut dari database.

Step 4: Setup Route

Route::controller(PostController::class)->group(function(){
    Route::get('posts/trash','trash')->name('posts.trash');
    Route::post('posts/{id}/restore','restore')->name('posts.restore');
    Route::delete('posts/{id}/delete','delete')->name('posts.delete');
});
Enter fullscreen mode Exit fullscreen mode

Oke, lanjut ke setup route. Disini saya akan memperkenalkan hal yang baru lagi di laravel 9 yang sebenarnya juga sudah ada di versi 8 terakhir. Hal yang baru tersebut adalah route group by controller. Jadi, jika kita punya route yang mempunyai Controller yang sama, kita bisa membungkusnya seperti kode di atas.

Silahkan copy code di atas, lalu paste pada file routes/web.php dan letakkan di atas Route::resource('posts',PostController::class);

Step 5: Setup Action Button

<td>
    <div class="d-flex">
        <a href="{{ route('posts.edit',$post->id) }}" class="btn btn-success">Edit</a>
        <form method="POST" action="{{ route('posts.destroy', $post->id) }}">
            @method('DELETE')
            @csrf
            <button type="submit" class="btn btn-danger ms-1 show_confirm" data-toggle="tooltip" title='Delete'>Delete</button>
        </form>
    </div>
</td>
Enter fullscreen mode Exit fullscreen mode

Kita lanjut lagi ke step setup action button. Karena untuk view index dan trash kita menggunakan file view yang sama yaitu index.blade.php, jadi kita perlu membedakan button-button yang ada di index atau trash. Silahkan buka file index.blade.php, cari code seperti di atas, lalu replace dengan code seperti di bawah ini.

<div class="d-flex">
    @if (request()->routeIs('posts.index'))
        <a href="{{ route('posts.edit',$post->id) }}" class="btn btn-success">Edit</a>
    @else
        <form action="{{ route('posts.restore',$post->id) }}" method="POST">
        @csrf
        <button type="submit" class="btn btn-success">Restore</button>
        </form>
    @endif

    <form method="POST" action="{{ request()->routeIs('posts.index') ? route('posts.destroy', $post->id) : route('posts.delete', $post->id) }}">
        @method('DELETE')
        @csrf
        <button type="submit" class="btn btn-danger ms-1 show_confirm" data-toggle="tooltip" title='Delete'>Delete</button>
    </form>
</div>
Enter fullscreen mode Exit fullscreen mode

Disini, jika kita berada di route posts.index , kita ingin menampilkan Edit dan Delete (Softdeletes) button. Tapi jika kita berada di route posts.trash , maka button yang ditampilkan adalah Restore dan Delete (Permanent) button.

Step 6: Testing

softdeletes laravel 9

Well, setelah melakukan langkah-langkah mulai dari membuat migration baru, setup controller, setup route dan setup action button, sekarang waktunya untuk testing. Silahkan jalankan laravel project kalian dengan perintah php artisan serve, lalu buka pada browser dengan URL 127.0.0.1:{port}/posts atau crud-laravel9.test/posts. Kemudian coba delete salah satu data, maka data tersebut akan dipindahkan ke halaman crud-laravel9.test/posts/trash seperti gambar di atas.

Cek juga di table posts, data yang telah kamu hapus (softdeletes) tersebut, sekarang mempunyai value pada field deleted_at. Untuk mengembalikan lagi ke data posts atau ingin me-restorenya, kamu bisa klik button restore. Dan jika ingin menghapusnya secara permanent, kita bisa klik delete button.

Demikianlah artikel kali ini yang telah membahas bagaimana cara implementasi softdeletes di laravel 9. Pada artikel selanjutnya, saya akan menuliskan artikel yang akan membahas bagaimana cara membuat fitur search atau pencarian di laravel 9. Semoga artikel ini dapat mudah dipahami dan membantu. Terimakasih banyak dan sampai jumpa di artikel berikutnya. 👋

Top comments (0)