When you install Laravel it has basic scaffolding. It has beautiful updated the Landing Page of 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
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
$ php artisan make:model products
Model created successfully.
$
Creating Migration
$ php artisan make:migration products
Created Migration: 2020_11_07_075702_create_products_table
$
Creating Controller
$ php artisan make:controller products
Controller created successfully.
$
Creating Model Migration and Controller
$ 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
<?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.
<?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.
Column | Detail | Data Type |
---|---|---|
Name | Product Name | String |
Brand | Product Brand | String |
Price | Product Price | Number |
ID | Create a id automatically | Number |
TimeStamp | Maintain the Created and Last modified timestamp | DateTime |
<?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.
<!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>
@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
@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
@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
@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