cover image
Nitish Kumar Singh
Nitish Kumar Singh
Clock Image 16 minutes
Posted on
November 7, 2020

CRUD in Laravel 8


When you install Laravel it has basic scaffolding. It has beautiful updated the Landing Page of Laravel 8.

Lading Page Laravel 8

What is CRUD? #

  • Create
  • Read
  • Update
  • Delete

CRUD is a term which refer to Create, Read, Update and Delete. These four operation are fundamental for building any backend. Now a days almost every backend is using database.

When you are using database you will do these operation. So, if you know these operation then you can probably you can make most of application of now a days.

Getting Started #

I hope you have installed Laravel and you are ready to get started with writing code. I will not talk about installation because there is good documentation about installing on Laravel website.

https://laravel.com/docs/8.x#installation

Once you install the project then we will create a new project

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

Creating files using Command #

Laravel is one of the best framework and it has outstanding CLI. you can create model, migration and controller using CLI. This make life a lot easier.

Creating Model #

To Create model you can use the command

Terminal
$ php artisan make:model products
Model created successfully.
$ 

Creating Migration #

Terminal
$ php artisan make:migration products
Created Migration: 2020_11_07_075702_create_products_table
$ 

Creating Controller #

Terminal
$ php artisan make:controller products
Controller created successfully.
$

Creating Model Migration and Controller #

Terminal
$ php artisan make:model products -mc 
Model created successfully.
Created Migration: 2020_11_07_075702_create_products_table
Controller created successfully.
$ 

Controller #

If you have used laravel earlier then there is no major change you will find in the controller. There is one small change which I will talk at then end of this section.

There is four operation CRUD and for that we need at least 7 methods in our controller.

  • Reading all the data - index
  • Reading only one data - read
  • Form for Creating data - create
  • Storing data of data - store
  • Form for Editing data - edit
  • Storing update of data - update
  • Delete Data - delete
app/Http/Controllers/ProductController.php
<?php

namespace App\Http\Controllers;
use App\Models\Product;
use Illuminate\Http\Request;

class ProductController extends Controller
{
    public function index(){
        return "Read";
    }
    public function read(){
        return "Read";
    }
    public function create(){
        return "Create";
    }
    public function store(){
        return "Store";
    }
    public function edit(){
        return "Edit";
    }
    public function update(){
        return "Update";
    }
    public function delete(){
        return "Delete";
    }
}

Routes #

This has some major change, I am calling this as major change because this change requires us to refactor all the code.

web.php
<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ProductController; // Added this line
/*
|--------------------------------------------------------------------------
| 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::get('/', function () {
//     return view('welcome');
// });

Route::get('/', [ProductController::class, 'index'])->name('product.home');

Route::get('/create', [ProductController::class, 'create'])->name('product.create');
Route::post('/create', [ProductController::class, 'store'])->name('product.store');

Route::get('/{id}/edit', [ProductController::class, 'edit'])->name('product.edit');
Route::put('/{id}/edit', [ProductController::class, 'update'])->name('product.update');

Route::delete('/{id}', [ProductController::class, 'delete'])->name('product.delete');
Route::get('/{id}', [ProductController::class, 'read'])->name('product.read');

Database Schema #

Before getting into the frontend let’s build our database and table.

ColumnDetailData Type
NameProduct NameString
BrandProduct BrandString
PriceProduct PriceNumber
IDCreate a id automaticallyNumber
TimeStampMaintain the Created and Last modified timestampDateTime
database/migrations/2020_11_07_081709_create_products_table.php
<?php

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

class CreateProductsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->integer('price');
            $table->string('brand');
            $table->timestamps();
        });
    }

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

Building UI #

We will use blade, a laravel templating engine. This will gives us power to build UI super quick using various programming php syntax in UI. We can also inherit the file for templating. We don’t need to add the header and footer in different file and include at top and footer like old school days.

First of all, We will create a template file which will look similar to this one.

resources/views/layouts/app.blade.php
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>CRUD APP</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" />
</head>
<body>
    <div id="app">
        <nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
            <div class="container">
                <a class="navbar-brand" href="{{ url('/') }}">
                    CRUD APP
                </a>
            </div>
        </nav>

        <main class="py-4">
            @yield('content')
        </main>

    </div>
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>
</html>

resources/views/product/add.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-8">
            @if (session('status'))
            <div class="alert alert-success">
                {{ session('status') }}
            </div>
            @endif
            <div class="card">
                <div class="card-header">Add Product Form</div>
                <div class="card-body">
                    <form action="{{ route('product.store')}}" method="POST">
                        @csrf
                        <div class="form-group">
                            <label for="name">Name</label>
                            <input type="text" 
                            class="form-control {{  $errors->has('name') ? 'is-invalid' :'' }}" 
                            name="name" id="name" value="{{ old('name')}}">
                            <div class="invalid-feedback">
                                {{ $errors->getBag('default')->first('name') }}
                            </div>
                        </div>

                        <div class="form-group">
                            <label for="price">Price</label>
                            <input type="number" 
                                class="form-control {{  $errors->has('price') ? 'is-invalid' :'' }}" 
                                name="price" id="price" value="{{ old('price')}}">
                            <div class="invalid-feedback">
                                {{ $errors->getBag('default')->first('price') }}
                            </div>
                        </div>

                        <div class="form-group">
                            <label for="brand">Brand</label>
                            <input type="text" 
                                class="form-control {{  $errors->has('brand') ? 'is-invalid' :'' }}" 
                                name="brand" id="brand" value="{{ old('brand')}}">
                            <div class="invalid-feedback">
                                {{ $errors->getBag('default')->first('brand') }}
                            </div>

                        </div>
                        <button type="submit" class="btn btn-primary btn-block">Save</button>
                    </form>
                </div>
            </div>

        </div>
    </div>
</div>

@endsection
resources/views/product/edit.blade.php
@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-8">
            @if (session('status'))
            <div class="alert alert-success">
                {{ session('status') }}
            </div>
            @endif
            <div class="card">
                <div class="card-header">Add Product Form</div>
                <div class="card-body">
                    <form action="{{ route('product.update', ['id' => $data->id])}}" method="POST">
                        @csrf
                        <input type="hidden" value="PUT" name="_method">
                        <div class="form-group">
                            <label for="id">ID</label>
                            <input type="text" 
                                class="form-control" 
                                name="id" id="id" value="{{$data->id}}" readonly>
                        </div>
                        <div class="form-group">
                            <label for="name">Name</label>
                            <input type="text" 
                            class="form-control {{  $errors->has('name') ? 'is-invalid' :'' }}" 
                            name="name" id="name" value="{{ old('name') ?? $data->name  }}">
                            <div class="invalid-feedback">
                                {{ $errors->getBag('default')->first('name') }}
                            </div>
                        </div>

                        <div class="form-group">
                            <label for="price">Price</label>
                            <input type="number" 
                                class="form-control {{  $errors->has('price') ? 'is-invalid' :'' }}" 
                                name="price" id="price" value="{{ old('price') ?? $data->price }}">
                            <div class="invalid-feedback">
                                {{ $errors->getBag('default')->first('price') }}
                            </div>
                        </div>

                        <div class="form-group">
                            <label for="brand">Brand</label>
                            <input type="text" 
                                class="form-control {{  $errors->has('brand') ? 'is-invalid' :'' }}" 
                                name="brand" id="brand" value="{{ old('brand') ?? $data->brand}}">
                            <div class="invalid-feedback">
                                {{ $errors->getBag('default')->first('brand') }}
                            </div>
                        </div>

                        <button type="submit" class="btn btn-primary btn-block">Update</button>
                    </form>
                </div>
            </div>

        </div>
    </div>
</div>

@endsection
resources/views/product/home.blade.php
@extends('layouts.app')

@section('content')
<div class="container">
    @if (session('status'))
    <div class="alert alert-success">
        {{ session('status') }}
    </div>
    @endif

    <div class="d-flex justify-content-end mb-2">
    <a href="{{ route('product.create') }}" class="btn btn-primary">Add Product</a>
    </div>

    <table class="table table-bordered">
        <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Price</th>
            <th>Action</th>
        </tr>
        @foreach ($data as $product)
        <tr>
            <td>{{ $product->id }}</td>
            <td>{{ $product->name }}</td>
            <td>{{ $product->price }}</td>
            <td>
                <a href="{{ route('product.read',  ['id' => $product->id] )}}" class="btn btn-primary">View</a>
                <a href="{{ route('product.edit', ['id' => $product->id] )}}" class="btn btn-warning">Edit</a>
            </td>
        </tr>
        @endforeach
    </table>
</div>

@endsection
resources/views/product/view.blade.php
@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-8">
            <table class="table table-bordered">
                <tr>
                    <th>ID</th>
                    <td>{{ $data->id }}</td>
                </tr>
                <tr>
                    <th>Name</th>
                    <td>{{ $data->name }}</td>
                </tr>
                <tr>
                    <th>Price</th>
                    <td>{{ $data->price }}</td>
                </tr>
                <tr>
                    <th>Brand</th>
                    <td>{{ $data->brand }}</td>
                </tr>
            </table>
            <div class="row">
                <div class="col">
                    <a href="{{ route('product.edit', ['id' => $data->id ]) }}" class="btn btn-primary">Edit</a>
                </div>
                <div class="col">
                    <a href="{{route('product.delete', ['id' => $data->id ])}}" 
                        class="btn btn-danger"
                        onclick="event.preventDefault();document.getElementById('delete-form').submit();"
                        >
                        Delete
                    </a>

                    <form id="delete-form" action="{{ route('product.delete', ['id' => $data->id ]) }}" method="POST" class="d-none">
                        @csrf
                        <input type="hidden" name="_method" value="delete">
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>

@endsection
Last updated at Sunday, Nov 8, 2020 by Nitish Kumar Singh
comments powered by Disqus

Subscribe to our Newsletter


Tweet this article