Laravel 9 Basic CRUD Operation with Pagination for Beginner

Sovary June 25, 2022 1.67K
12 minutes read

In this article you will learn how to build basic CRUD operations in Laravel 9. We will give simple example about student management board to add, update, delete, and remove the student from the list with pagination. Moreover we will validate and show message if there are any error occure.

thumbnail laravel 9 crud pagination example tutorial

In computer programming context CRUD is short form of four functions Create, Read, Update, Delete. These functions mostly in all management application are required to manipulate data from database.

CRUD Operation in Laravel 9 Example

  • Step 1 - Install Laravel 9 & Setup Database
  • Step 2 - Create Model and Migration
  • Step 3 - Create Controller
  • Step 4 - Adding Route
  • Step 5 - Create View (Blade files)
  • Step 6 - Configure Pagination Style
  • Step 7 - Run Laravel Server

Step 1 - Install Laravel 9 & Setup Database

You have to installed Laravel framework. Read this to know how to install Laravel project with database.

Step 2 - Create Model and Migration

We will create a table to store student info which have some properties. In Laravel we required to create model and run migration to generate table in database. Make sure you have update database connection successfully. To generate migration file and model file, you may use the --migration or -m option. See below command:

Create Model

php artisan make:model Student -m

Update Migration

Open file database -> migrations -> 2022_06_23_033722_create_students_table.php

<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('students', function (Blueprint $table) {
            $table->id();
            $table->string('first_name');
            $table->string('last_name');
            $table->string('gender');
            $table->date('dob');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('students');
    }
};

After updated and save file, run below command to create a table in database.

php artisan migrate

Step 3 - Create Controller

We will define business logic in controller file, but we have to run below command to create controller file. To generate resources (CRUD) function you may use the --resource or -r option. See below command:

php artisan make:controller -r StudentController

The command will generate a file StudentController.php and create all methods resource, the thing we need to do is to implement all exiting functions. We will implement action to manipulate with database such as: store data, update data, remove data, and read data. The resource methods will create as below 

NOTE: Do Not Change Method Name, Unless It Will Not Work with the Below Route.

  1. index() - to display list of students
  2. create() - to display UI insert form student
  3. store() - to save data from UI insert form
  4. show() - to display a specific student
  5. edit() - to display UI edit form student
  6. update() - to save data from UI edit form
  7. destroy() - to submit delete data student

Open file app -> Http -> Controllers -> StudentController.php

<?php

namespace App\Http\Controllers;

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

class StudentController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $data['students'] = Student::orderBy('id','desc')->paginate(5);
        return view('student.index', $data);
    }

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

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $request->validate([
            'first_name' => 'required',
            'last_name' => 'required',
            'gender' => 'required',
            'dob' => 'required'
            ]);
        $student = new Student;
        $student->first_name = $request->first_name;
        $student->last_name = $request->last_name;
        $student->gender = $request->gender;
        $student->dob = $request->dob;
        $student->save();
        return redirect()->route('student.index')
        ->with('success','Student has been created successfully.');
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        return view('student.show',["student"=>Student::find($id)]);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        
        return view('student.edit',["student"=>Student::find($id)]);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $request->validate([
            'first_name' => 'required',
            'last_name' => 'required',
            'gender' => 'required',
            'dob' => 'required'
            ]);
        $student = Student::find($id);
        $student->first_name = $request->first_name;
        $student->last_name = $request->last_name;
        $student->gender = $request->gender;
        $student->dob = $request->dob;
        $student->save();
        return redirect()->route('student.index')
        ->with('success','Student has been updated successfully.');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        Student::find($id)->delete();
        return redirect()->route('student.index')
                        ->with('success','Product deleted successfully');
    }
}

Step 4 - Adding Route

Next we are going to add route which is link between blade file and controller, but in this case we have only single route to perform all request and methods.

Open file routes -> web.php

<?php

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

/*
|--------------------------------------------------------------------------
| 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('student', StudentController::class);

Route::resource will perform action match to method in controller and HTTP request method. Again, do not change method name in controller file.

Step 5 - Create View (Blade files)

Now we are going to create blade files inside a directory named "student"  and files to create are index.blade.php, create.blade.php, edit.blade.php, show.blade.php, and layout.blade.php.

We will create layout.blade.php as parent template so all layout will extend from this template.

Create file resources -> views -> student -> layout.blade.php

<!DOCTYPE html>
<html>
<head>
    <title>Laravel 9 CRUD Student Management cambotutorial.com</title>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
  
<div class="container">
    @yield('content')
</div>
   
</body>
</html>

@yield keyword in blade file will help all the layout pages which are extending the template will put their content into it.

Create file resources -> views -> student -> index.blade.php

@extends('student.layout')
@section('content')
    <div class="row">
        <div class="col-lg-12">
            <div class="card">
                <div class="card-header">
                <a href="{{ route('student.create') }}" class="btn btn-primary">Insert</a>
                </div>
                <div class="card-body">
                @if ($message = Session::get('success'))
                    <div class="alert alert-success">
                        <p>{{ $message }}</p>
                    </div>
                @endif                
                <table class="table table-bordered">
                    <tr>
                        <th>No</th>
                        <th>First Name</th>
                        <th>Last Name</th>
                        <th>Gender</th>
                        <th>DOB</th>
                        <th width="280px">Action</th>
                    </tr>
                    @foreach ($students as $st)
                    <tr>
                        <td>{{ $st->id }}</td>
                        <td>{{ $st->first_name }}</td>
                        <td>{{ $st->last_name }}</td>
                        <td>{{ $st->gender }}</td>
                        <td>{{ $st->dob }}</td>
                        <td>
                        <form action="{{ route('student.destroy',$st->id) }}" method="POST">
                            <a class="btn btn-info" href="{{ route('student.show',$st->id) }}">Show</a>
                            <a class="btn btn-primary" href="{{ route('student.edit',$st->id) }}">Edit</a>
                            @csrf
                            @method('DELETE')
                            <button type="submit" class="btn btn-danger">Delete</button>
                        </form>
                        </td>
                    </tr>
                    @endforeach
                </table>
                </div>
            </div>
        </div>
    </div>
    <div class="d-flex">
    {!! $students->links() !!}
    </div>
    
@endsection

{!! $students->links() !!} will generated pagination in Laravel 9, but the style will not work propertly with Bootstrap 5. We will configure in next step after create blade files.

Create file resources -> views -> student -> create.blade.php

@extends('student.layout')
@section('content')
<div class="row">
        <div class="col-lg-12">
            <div class="card">
                <div class="card-header">
                    <a href="{{ route('student.index') }}" class="btn btn-success">Back</a>
                </div>
                <div class="card-body">
                @if ($errors->any())
                    <div class="alert alert-danger">
                        <ul>
                            @foreach ($errors->all() as $error)
                                <li>{{ $error }}</li>
                            @endforeach
                        </ul>
                    </div>
                @endif
                <h5 class="card-title text-center">Insert New Student</h5>
                <form action="{{ route('student.store') }}" method="POST">
                    @csrf
                    <div class="mb-3">
                        <label  class="form-label">First Name</label>
                        <input type="text" class="form-control" name="first_name" placeholder="First Name">
                    </div>
                    <div class="mb-3">
                        <label  class="form-label">Last Name</label>
                        <input type="text" class="form-control" name="last_name" placeholder="Last Name">
                    </div>
                    <div class="mb-3">
                        <label  class="form-label">Gender</label>
                        <select class="form-select" name="gender">
                            <option selected value ="male">Male</option>
                            <option value ="female">Female</option>
                        </select>
                    </div>
                    <div class="mb-3">
                        <label  class="form-label">Date of Birth</label>
                        <input type="date" value="1994-03-12" name="dob" class="form-control">
                    </div>
                    <div class="d-grid gap-2">
                    <button class="btn btn-primary" type="submit">Save</button>
                    </div>
                </form>
                </div>
            </div>
        </div>
    </div>
</div>      
@endsection

Create file resources -> views -> student -> edit.blade.php

@extends('student.layout')
@section('content')
<div class="row">
        <div class="col-lg-12">
            <div class="card">
                <div class="card-header">
                <a href="{{ route('student.index') }}" class="btn btn-success">Back</a>
                </div>
                <div class="card-body">
                @if ($errors->any())
                    <div class="alert alert-danger">
                        <ul>
                            @foreach ($errors->all() as $error)
                                <li>{{ $error }}</li>
                            @endforeach
                        </ul>
                    </div>
                @endif
                <h5 class="card-title text-center">Edit Student</h5>
                <form action="{{ route('student.update', $student->id) }}" method="POST">
                    @csrf
                    @method('PUT')
                    <div class="mb-3">
                        <label  class="form-label">First Name</label>
                        <input type="text" value="{{$student->first_name}}"  name="first_name"  class="form-control" placeholder="First Name">
                    </div>
                    <div class="mb-3">
                        <label  class="form-label">Last Name</label>
                        <input type="text" value="{{$student->last_name}}" name="last_name"  class="form-control" placeholder="Last Name">
                    </div>
                    <div class="mb-3">
                        <label  class="form-label">Gender</label>
                        <select class="form-select" name="gender">
                            @if($student->gender == "male")
                            <option value ="male" selected>Male</option>
                            <option value ="female">Female</option>
                            @else
                            <option value ="male">Male</option>
                            <option value ="female" selected>Female</option>
                            @endif
                        </select>
                    </div>
                    <div class="mb-3">
                        <label  class="form-label">Date of Birth</label>
                        <input type="date" value="{{$student->dob}}"  name="dob"  class="form-control">
                    </div>
                    <div class="d-grid gap-2">
                        <button class="btn btn-primary" type="submit">Save</button>
                    </div>
                </form>
                </div>
            </div>
        </div>
    </div>
</div>      
@endsection

Create file resources -> views -> student -> show.blade.php

@extends('student.layout')
@section('content')
<div class="row">
        <div class="col-lg-12">
            <div class="card">
                <div class="card-header">
                    <a href="{{ route('student.index') }}" class="btn btn-success">Back</a>
                </div>
                <div class="card-body">
                <h5 class="card-title text-center">Student Info</h5>
                <div class="mb-3">
                <label class="form-label">Name</label>
                <input type="text" disabled class="form-control" value="{{ $student->first_name }} {{$student->last_name}}">
                </div>
                <div class="mb-3">
                <label class="form-label">Gender</label>
                <input type="text" disabled class="form-control" value="{{$student->gender}}">
                </div>
                <div class="mb-3">
                <label class="form-label">Date of Birth</label>
                <input type="text" disabled class="form-control" value="{{$student->dob}}">
                </div>
                </div>
            </div>
        </div>
    </div>
</div>      
@endsection

Step 6 - Configure Pagination Style

Next step I will show you how to configure pagination style with Bootstrap 5

Open file app -> Providers ->AppServiceProvider.php

<?php

namespace App\Providers;
...

use Illuminate\Pagination\Paginator;

class AppServiceProvider extends ServiceProvider
{
    ...

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Paginator::useBootstrap();
    }
}

Step 7 - Run Laravel Server

Now our CRUD application is ready to run. Run command below to start Laravel server

php artisan serve

To see the output in browser, go to http://localhost:8000/

crud paging laravel 9 for beginner

 

crud paging laravel 9 for beginner edit form

Hope this tutorial help you to finished the project. Have a nice day !

You might Also Like:

 

Laravel  PHP  Laravel 9 
Author

As the founder and passionate educator behind this platform, I’m dedicated to sharing practical knowledge in programming to help you grow. Whether you’re a beginner exploring Machine Learning, PHP, Laravel, Python, Java, or Android Development, you’ll find tutorials here that are simple, accessible, and easy to understand. My mission is to make learning enjoyable and effective for everyone. Dive in, start learning, and don’t forget to follow along for more tips and insights!. Follow him