How to Build a Laravel 11 CRUD Application: A Step-by-Step Tutorial

by | Feb 10, 2025 | Insights

With 18 years of experience, I’ve created over 200 websites around the world, from America to Europe and Asia. I specialise in Frontend, Backend, WordPress, and Laravel, building sites that are both beautiful and functional. My work is all about turning ideas into reliable and easy-to-use solutions. By working together, we can build a strong online presence for your business. Let’s bring your digital vision to life and reach new levels of success.

In this tutorial, I’ll guide you through creating a simple CRUD (Create, Read, Update, Delete) application in Laravel 11. Whether you’re new to Laravel or looking to refresh your knowledge, this step-by-step guide will help you grasp the fundamentals of building a dynamic and maintainable web application.

What is CRUD?

CRUD is an acronym for Create, Read, Update, and Delete, which are the four basic operations for managing data in most web applications. A CRUD interface allows users to add new records to a database, read (or display) existing records, modify records, and remove records when they are no longer needed.

Why Use Laravel 11?

Laravel has long been celebrated for its elegant syntax, robust toolset, and active community. The version 11 framework continues to build upon these strengths, offering:

  1. Eloquent ORM Enhancements – Making database operations more intuitive.
  2. Improved Security and Performance – Ensuring your applications run efficiently and remain secure.
  3. Streamlined Dependency Updates – Helping you stay up-to-date with the latest PHP standards.

Let’s get started on building our CRUD application.

1. Setting Up Your Laravel 11 Project

Before diving in, make sure you have the following installed on your machine:

  • PHP 8.1+ (or the most recent version recommended by Laravel)
  • Composer (PHP’s dependency manager)
  • MySQL (or another database like PostgreSQL or SQLite)

Create a New Laravel Project

Open your terminal and navigate to the directory where you want to create your new project. Then run:

composer create-project laravel/laravel laravel-crud-app

This command will create a new Laravel project in a folder named laravel-crud-app.

2. Configuring Your Database

After installing your Laravel project, set up your database connection. In your project directory, locate the .env file and update the following lines according to your database credentials:

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

Make sure the DB_DATABASE name matches an existing database on your system (or create a new one).

3. Creating a Migration and Model

Let’s create a simple model to demonstrate CRUD operations. In this example, we’ll build a basic “Post” model to store blog post data (title, content, etc.).

Generate the Model and Migration

In the terminal, run:

php artisan make:model Post -m

This command does two things:

  • Creates a Post model in the app/Models directory.
  • Creates a migration file in the database/migrations directory.

Define the Migration Schema

Open the newly created migration file in database/migrations/xxxx_xx_xx_create_posts_table.php and update the up() method:

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->text('content');
        $table->timestamps();
    });
}

When you’re done, run:

php artisan migrate

This command creates the posts table in your database.

4. Setting Up Routes

Our application will require routes to handle requests. We’ll use a Resource Controller, which automatically creates routes for basic CRUD operations (index, create, store, show, edit, update, and destroy).

Create a Resource Controller

Run the following command:

php artisan make:controller PostController --resource

This generates a PostController class in app/Http/Controllers. It will have empty methods that map to the standard CRUD operations.

Register the Resource Route

Open the routes/web.php file and add:

use AppHttpControllersPostController;

Route::resource('posts', PostController::class);

Now, Laravel knows how to handle /posts routes for each of the CRUD actions.

5. Implementing CRUD in the Controller

Open the PostController.php file in app/Http/Controllers. You’ll see several methods: index, create, store, show, edit, update, and destroy.

5.1 Index (Listing All Posts)

public function index()
{
    $posts = Post::all(); // Retrieve all posts
    return view('posts.index', compact('posts'));
}

5.2 Create (Show Form to Add a New Post)

public function create()
{
    return view('posts.create');
}

5.3 Store (Handle Form Submission for New Post)

public function store(Request $request)
{
    // Validate incoming data
    $request->validate([
        'title' => 'required',
        'content' => 'required',
    ]);

    // Save the post
    Post::create([
        'title' => $request->title,
        'content' => $request->content,
    ]);

    // Redirect with a success message
    return redirect()->route('posts.index')->with('success', 'Post created successfully!');
}

Make sure your Post model has the $fillable property set to allow mass assignment. In app/Models/Post.php, add:

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

5.4 Show (Display a Single Post)

public function show(Post $post)
{
    return view('posts.show', compact('post'));
}

5.5 Edit (Show Form to Edit an Existing Post)

public function edit(Post $post)
{
    return view('posts.edit', compact('post'));
}

5.6 Update (Handle Form Submission for Editing)

public function update(Request $request, Post $post)
{
    // Validate incoming data
    $request->validate([
        'title' => 'required',
        'content' => 'required',
    ]);

    // Update the post
    $post->update([
        'title' => $request->title,
        'content' => $request->content,
    ]);

    return redirect()->route('posts.index')->with('success', 'Post updated successfully!');
}

5.7 Destroy (Delete a Post)

public function destroy(Post $post)
{
    $post->delete();
    return redirect()->route('posts.index')->with('success', 'Post deleted successfully!');
}

6. Building the Views

Next, we’ll create simple Blade templates for each action. Inside the resources/views directory, create a new folder named posts, and add these files: index.blade.php, create.blade.php, show.blade.php, edit.blade.php.

6.1 index.blade.php

@extends('layouts.app')

@section('content')
    <div class="container">
        <h1>All Posts</h1>
        @if(session('success'))
            <div>{{ session('success') }}</div>
        @endif
        <a href="{{ route('posts.create') }}">Create New Post</a>

        <ul>
            @foreach($posts as $post)
                <li>
                    <a href="{{ route('posts.show', $post->id) }}">{{ $post->title }}</a>
                    <a href="{{ route('posts.edit', $post->id) }}">Edit</a>
                    <form action="{{ route('posts.destroy', $post->id) }}" method="POST" style="display:inline-block;">
                        @csrf
                        @method('DELETE')
                        <button type="submit">Delete</button>
                    </form>
                </li>
            @endforeach
        </ul>
    </div>
@endsection

6.2 create.blade.php

@extends('layouts.app')

@section('content')
    <div class="container">
        <h1>Create New Post</h1>

        @if($errors->any())
            <div>
                @foreach($errors->all() as $error)
                    <div>{{ $error }}</div>
                @endforeach
            </div>
        @endif

        <form action="{{ route('posts.store') }}" method="POST">
            @csrf
            <div>
                <label for="title">Title:</label>
                <input type="text" name="title" id="title" value="{{ old('title') }}">
            </div>
            <div>
                <label for="content">Content:</label>
                <textarea name="content" id="content">{{ old('content') }}</textarea>
            </div>
            <button type="submit">Save</button>
        </form>
    </div>
@endsection

6.3 show.blade.php

@extends('layouts.app')

@section('content')
    <div class="container">
        <h1>{{ $post->title }}</h1>
        <p>{{ $post->content }}</p>
        <a href="{{ route('posts.index') }}">Back to All Posts</a>
    </div>
@endsection

6.4 edit.blade.php

@extends('layouts.app')

@section('content')
    <div class="container">
        <h1>Edit Post</h1>

        @if($errors->any())
            <div>
                @foreach($errors->all() as $error)
                    <div>{{ $error }}</div>
                @endforeach
            </div>
        @endif

        <form action="{{ route('posts.update', $post->id) }}" method="POST">
            @csrf
            @method('PUT')

            <div>
                <label for="title">Title:</label>
                <input type="text" name="title" id="title" value="{{ old('title', $post->title) }}">
            </div>
            <div>
                <label for="content">Content:</label>
                <textarea name="content" id="content">{{ old('content', $post->content) }}</textarea>
            </div>
            <button type="submit">Update</button>
        </form>
    </div>
@endsection

7. Creating a Layout (Optional)

For a more polished look and feel, you can create a layout file resources/views/layouts/app.blade.php that includes shared HTML (like headers, footers, or navigation):

<!DOCTYPE html>
<html>
<head>
    <title>Laravel 11 CRUD</title>
</head>
<body>
    @yield('content')
</body>
</html>

All the view files extend layouts.app, ensuring a consistent layout across the application.

8. Testing Your Application

With your routes and views set up, you can run the Laravel development server:

php artisan serve

Open your browser and visit http://127.0.0.1:8000/posts. You should see the list of posts (initially empty). From here, you can create, edit, show, or delete posts to verify that everything is functioning correctly.

Conclusion

Congratulations! You’ve just built a Laravel 11 CRUD application. You now have a basic framework to manage records in your database, which can be adapted to fit virtually any project. By mastering CRUD fundamentals, you can easily scale up to more advanced features like user authentication, pagination, file uploads, and API integrations.

Remember, the key to developing robust Laravel applications is organisation and best practices. Keep your code clean, follow Laravel’s conventions, and regularly update your dependencies to maintain a secure, high-performance site.

If you need further help or want to discuss custom functionality for your next big idea, feel free to get in touch. With 18 years of experience and over 200 websites built worldwide, I’m here to help your business thrive online. Let’s bring your digital vision to life and reach new levels of success together.

Ready to build something great?
Contact me and let’s start crafting your perfect web solution today!