Laravel 11 CRUD Operation Tutorial with Example from Scratch

In this Laravel 11 CRUD tutorial, we’ll guide you through a straightforward, step-by-step example of how to create a CRUD operation in laravel from scratch. With each new release, Laravel introduces exciting features, and Laravel 11 is no exception. For beginners, mastering CRUD operations is often the first step to solidify their understanding of Laravel’s capabilities.

As you’re likely aware, CRUD stands for Create, Read, Update, and Delete – essential functions for manipulating data in a database. Throughout this tutorial, we’ll walk you through the creation of a basic CRUD application in Laravel 11, covering each operation in detail.

By following along with this tutorial, you’ll gain practical experience in building a fully functional CRUD application in Laravel 11, complete with validation and a user-friendly interface.

Step for Laravel 11 CRUD Example

Use the following steps to implement a basic crud operation in laravel application.

  • Download Laravel Appa
  • Connect Database to App
  • Create Model & Migration
  • Add Routes
  • Create Resource Controller
  • Create Blade Files
  • Run Laravel Application and Test

#1 Install Laravel 11

Before proceeding with the installation of Laravel 11, ensure that your system meets the following prerequisites:

  • Laravel 11 requires PHP version 8.2 or higher. You can verify your PHP version by running php -v in your terminal or command prompt. If you don’t have PHP 8.2 installed, you’ll need to upgrade your PHP version.
  • Laravel supports multiple database systems such as MySQL, PostgreSQL, SQLite, and SQL Server. In Laravel 11, they have predefined DB_CONNECTION=sqlite in the .env file, but if you are using MySQL, you will need to update it.

To install Laravel 11, run the following command in your terminal:

composer create-project --prefer-dist laravel/laravel:^11.0 laravel-crud-app

If you prefer to install Laravel based on your PHP version, use the following command:

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

#2 Setup Database

Now, you need to create the mysql database and connect that database to the Laravel application. So, open localhost/phpmyadmin and create a new database name then add the credentials in .env file which is showing in your project root.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravelblog #db_name
DB_USERNAME=root #db_username
DB_PASSWORD=admin #db_password

#3 Generate Model & Migration

After the project installation and connection with the database now it’s time to start the CRUD operation in Laravel 11. Here it would be best if you generated a model and migration. You need to run the following command in your terminal.

php artisan make:model Post -m

Now you can see in your database migration directory created a new file same as below, here you need to add your database columns.

database\migrations\2023_03_20_071913_create_posts_table.php

<?php

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

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->longText('description');
            $table->timestamps();
        });
    }
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

After adding the columns, now run the following command to generate the table in your database.

php artisan migrate

Add Fillable Property: In your app/models inside generate a new file Post.php file where you need to add fillable properties.

app\Models\Post.php

<?php

namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;
    protected $fillable = [
      'title', 'description'
    ];
}

#4 Create Routes for CRUD Operation

After the Laravel 8 routes section, some changes were applied in Laravel 9, but there are no changes in Laravel 11, so you can follow the same procedure. Here, you’ll need to use your controller and then initialize the controller class. Open your “routes/web.php” file and define your routes as follows:

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

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

Route::get('/', function () {
    return view('welcome');
});

#5 Create controller and Update Methods

After defining the controller class in route file you need to create a controller by just adding the below command and generate a new resource controller PostController.

php artisan make:controller PostController --resource

After running the above command, you’ll notice a new file named “PostController” in the directory “app/Http/Controllers”. Inside this file, you’ll find pre-created methods similar to the code provided below. You don’t need to add anything else; simply copy the code below and paste it into your “PostController” file.

app/Http/Controllers/PostController.php

<?php

namespace App\Http\Controllers;

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

class PostController extends Controller
{

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $posts = Post::all();
        return view('posts.index', compact('posts'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
       return view('posts.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $request->validate([
            'title' => 'required',
            'description' => 'required',
        ]);

        Post::create($request->all());

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

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function show(Post $post)
    {
      return view('posts.show',compact('post'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function edit(Post $post)
    {
        return view('posts.edit',compact('post'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Post $post)
    {
        $request->validate([
            'title' => 'required',
            'description' => 'required',
        ]);

        $post->update($request->all());

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

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Post  $post
     * @return \Illuminate\Http\Response
     */
    public function destroy(Post $post)
    {
        $post->delete();

        return redirect()->route('posts.index')
                        ->with('success','post deleted successfully');
    }

}

#6 Create a List, Form, and View Blade Files

After completing all the above steps, it’s time to create blade files that will be responsible for displaying lists, forms, and other elements in your application’s user interface.

In this step first, you need to create two folders inside the “resources/views” directory one is “layouts” and another is “posts”.

Inside the layouts folder, you will create an app.blade.php file. In the posts folder, you need to create another blade file.

NOTE: The app.blade.php will be created inside the “layouts” directory.

resources/views/layouts/app.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/css/bootstrap.css" rel="stylesheet">
</head>
<body>
  <div class="container">
       @yield('content')
  </div>
</body>
</html>

resources/views/posts/index.blade.php

@extends('layouts.app')
@section('content')
    <div class="row">
        <div class="col-lg-12 margin-tb">
            <div class="pull-left">
                <h2>Posts </h2>
            </div>
            <div class="pull-right">
                <a class="btn btn-success" href="{{ route('posts.create') }}"> Create New Product</a>
            </div>
        </div>
    </div>
    @if ($message = Session::get('success'))
        <div class="alert alert-success">
            <p>{{ $message }}</p>
        </div>
    @endif
    <table class="table table-bordered">
        <tr>
            <th>Title</th>
            <th>Description</th>
            <th>Action</th>
        </tr>
        @foreach ($posts as $post)
        <tr>
            <td>{{ $post->title }}</td>
            <td>{{ $post->description }}</td>
            <td>
                 <a class="btn btn-info" href="{{ route('posts.show', $post->id) }}">Show</a>
                    <a class="btn btn-primary" href="{{ route('posts.edit', $post->id) }}">Edit</a>
                <form action="{{ route('posts.destroy', $post->id) }}" method="POST">
                    @csrf
                    @method('DELETE')
                    <button type="submit" class="btn btn-danger">Delete</button>
                </form>
            </td>
        </tr>
        @endforeach
    </table>
@endsection

resources/views/posts/create.blade.php

Now all the below blade files will create inside the “posts” directory. First, create the “create.blade.php” file.

@extends('layouts.app')
@section('content')
<div class="row">
    <div class="col-lg-12 margin-tb">
        <div class="pull-left">
            <h2>Create Post</h2>
        </div>
        <div class="pull-right">
            <a class="btn btn-primary" href="{{ route('posts.index') }}"> Back</a>
        </div>
    </div>
</div>
@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif
<form action="{{ route('posts.store') }}" method="POST">
    @csrf
     <div class="row">
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Name:</strong>
                <input type="text" name="title" class="form-control" placeholder="Title">
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
              <strong>Description:</strong>
                <textarea class="form-control" style="height:150px" name="description" placeholder="Description"></textarea>
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12 text-center">
                <button type="submit" class="btn btn-primary">Save</button>
        </div>
    </div>
</form>
@endsection

resources/views/posts/edit.blade.php

Same as the create.blade.php file create another file “edit.blade.php” file inside the “posts” directory.

@extends('layouts.app')
@section('content')
    <div class="row">
        <div class="col-lg-12 margin-tb">
            <div class="pull-left">
                <h2>Edit Post</h2>
            </div>
            <div class="pull-right">
                <a class="btn btn-primary" href="{{ route('posts.index') }}"> Back</a>
            </div>
        </div>
    </div>
    @if ($errors->any())
        <div class="alert alert-danger">
            <ul>
                @foreach ($errors->all() as $error)
                    <li>{{ $error }}</li>
                @endforeach
            </ul>
        </div>
    @endif
    <form action="{{ route('posts.update',$post->id) }}" method="POST">
        @csrf
        @method('PUT')
         <div class="row">
            <div class="col-xs-12 col-sm-12 col-md-12">
                <div class="form-group">
                    <strong>Title:</strong>
                    <input type="text" name="title" value="{{ $post->title }}" class="form-control" placeholder="Title">
                </div>
            </div>
            <div class="col-xs-12 col-sm-12 col-md-12">
                <div class="form-group">
                    <strong>Description:</strong>
                    <textarea class="form-control" style="height:150px" name="description" placeholder="Description">{{ $post->description }}</textarea>
                </div>
            </div>
            <div class="col-xs-12 col-sm-12 col-md-12 text-center">
              <button type="submit" class="btn btn-primary">Submit</button>
            </div>
        </div>
    </form>
@endsection

resources/views/posts/show.blade.php

The show or read file also created inside the “posts” directory.

@extends('layouts.app')
@section('content')
    <div class="row">
        <div class="col-lg-12 margin-tb">
            <div class="pull-left">
                <h2> Show Post</h2>
            </div>
            <div class="pull-right">
                <a class="btn btn-primary" href="{{ route('posts.index') }}"> Back</a>
            </div>
        </div>
    </div>
    <div class="row">
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Title:</strong>
                {{ $post->title }}
            </div>
        </div>
        <div class="col-xs-12 col-sm-12 col-md-12">
            <div class="form-group">
                <strong>Description:</strong>
                {{ $post->description }}
            </div>
        </div>
    </div>
@endsection

Finally, the Laravel 11 CRUD Operation is complete. Today, you’ve learned how to create a basic Laravel CRUD example tutorial for beginners from scratch, step by step. Now, it’s time to test our CRUD application in the browser to ensure that the create, list, edit, update, show, and delete operations are working properly! Let’s start the application first by using the following command:

php artisan serve

Now that the app is running, you’ll see a http://localhost:8000 URL in your terminal. Our CRUD operations are accessible via the /posts route, so you should navigate to http://localhost:8000/posts in your browser to test the functionality.

Learn Also: Laravel Ajax CRUD Example Tutorial

Conclusion

I hope that the Laravel application for CRUD operations is functioning properly if you have followed the aforementioned steps.