How to Use Soft Delete in Laravel
How to Use Soft Delete in Laravel

How to Use Soft Delete in Laravel

Soft deleting is a feature in Laravel that allows you to mark records as deleted without actually removing them from the database. This can be particularly useful for restoring records later or keeping a record of deletions. In this article, we’ll walk through how to implement and use soft delete in Laravel, with easy-to-follow examples.

Step 1: Setting Up Your Environment

Before we start, ensure you have a Laravel project set up. If not, you can create one using the following command:

composer create-project --prefer-dist laravel/laravel soft-delete-example

Step 2: Creating a Model and Migration

Let’s create a model and migration for a simple Post entity. Use the following Artisan command:

php artisan make:model Post -m

This command will create a Post model and a migration file in the database/migrations directory.

Step 3: Updating the Migration

Open the migration file located in the database/migrations directory and update it to include the softDeletes column:

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

class CreatePostsTable extends Migration
{
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('content');
            $table->timestamps();
            $table->softDeletes(); // Add this line for soft deletes
        });
    }

    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

Run the migration to create the posts table:

php artisan migrate

Step 4: Enabling Soft Deletes in the Model

Next, open the Post model located in the app/Models directory and use the SoftDeletes trait:

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; // Use the SoftDeletes trait

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

Step 5: Performing Soft Deletes

Now, let’s create a simple controller to demonstrate soft deleting a post. Run the following command to create a controller:

php artisan make:controller PostController

Open the PostController and add the following methods:

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    public function index()
    {
        $posts = Post::all();
        return view('posts.index', compact('posts'));
    }

    public function store(Request $request)
    {
        Post::create($request->all());
        return redirect()->route('posts.index');
    }

    public function destroy($id)
    {
        $post = Post::find($id);
        $post->delete();
        return redirect()->route('posts.index');
    }

    public function restore($id)
    {
        $post = Post::withTrashed()->find($id);
        $post->restore();
        return redirect()->route('posts.index');
    }

    public function forceDelete($id)
    {
        $post = Post::withTrashed()->find($id);
        $post->forceDelete();
        return redirect()->route('posts.index');
    }
}

Step 6: Creating Routes

Update your web.php file to include routes for the above methods:

use App\Http\Controllers\PostController;

Route::resource('posts', PostController::class);
Route::post('posts/{post}/restore', [PostController::class, 'restore'])->name('posts.restore');
Route::delete('posts/{post}/force-delete', [PostController::class, 'forceDelete'])->name('posts.forceDelete');

Step 7: Creating Views

Create a view file named index.blade.php in the resources/views/posts directory:

<!-- resources/views/posts/index.blade.php -->

<!DOCTYPE html>
<html>
<head>
    <title>Soft Delete Example</title>
</head>
<body>
    <h1>Posts</h1>

    <form action="{{ route('posts.store') }}" method="POST">
        @csrf
        <input type="text" name="title" placeholder="Title">
        <textarea name="content" placeholder="Content"></textarea>
        <button type="submit">Create Post</button>
    </form>

    <h2>All Posts</h2>
    <ul>
        @foreach($posts as $post)
            <li>
                {{ $post->title }} - {{ $post->content }}
                <form action="{{ route('posts.destroy', $post->id) }}" method="POST" style="display:inline;">
                    @csrf
                    @method('DELETE')
                    <button type="submit">Delete</button>
                </form>
            </li>
        @endforeach
    </ul>

    <h2>Trashed Posts</h2>
    <ul>
        @foreach($posts->onlyTrashed() as $trashedPost)
            <li>
                {{ $trashedPost->title }} - {{ $trashedPost->content }}
                <form action="{{ route('posts.restore', $trashedPost->id) }}" method="POST" style="display:inline;">
                    @csrf
                    <button type="submit">Restore</button>
                </form>
                <form action="{{ route('posts.forceDelete', $trashedPost->id) }}" method="POST" style="display:inline;">
                    @csrf
                    @method('DELETE')
                    <button type="submit">Force Delete</button>
                </form>
            </li>
        @endforeach
    </ul>
</body>
</html>

Conclusion

You’ve now learned how to implement and use soft deletes in Laravel. With soft deletes, you can mark records as deleted without permanently removing them from the database, allowing for easy restoration or permanent deletion later. This feature is especially useful for keeping a record of deletions or temporarily hiding records.