How to Make Full Shop CRUD with DataTables in Laravel?

During the Web 2.0 days, CRUD operations were considered foundation of the most dynamic websites. Technically, CRUD operations means user can create, read, update and delete records on a webpage. Laravel enables us to make a CRUD application in just a few minutes. Let’s do the coding part for that. 

1. Installing Laravel

To install the new version of Laravel run following command into your terminal or command prompt.

composer create-project --prefer-dist laravel/laravel shopApp

2. Database Configuration

In order to configure the database we need to add these credentials in my .env file.

  • Database name
  • Database password
  • Database username
  • Database host

In order to do so, we will add the following lines in the .env file.

DB_HOST=localhost 
DB_DATABASE=shop_app_db 
DB_USERNAME=root 
DB_PASSWORD=secret

3. Creating model and migration

First we will create a model and migration by running this command.

php artisan make:model Product -m

-m will create a migration file in your migration folder.

After running that command I will add this code in the migration file mentioned below:

/database/migrations/2021_01_01_122345_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->text("description");
            $table->timestamps();
        });
    }

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

Now we will run the migration using the following command.

php artisan migrate

Let’s add below code in our Shop model. 

app/Product.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
	protected $fillable = [
		'name', 'price','description'
	];
}

4. Adding Resource Route

We need to add resource route for Shop CRUD application. So in your “routes/web.php” file add following route.

routes/web.php

Route::resource('products',ProductsController::class);

 

5. Creating Controller and Listing all routes

Now use the following command to create a ShopController. You’d observe the distinctive change as how all the methods are already added in ProductsController.

php artisan make:controller ProductsController --resource --model=Product

If you want to check routes then run following command and observe that every method is already mapped to the specific route already.

php artisan route:list

Now we will add following code in our ShopController to make it a proper CRUD application. 

app/Http/Controllers/ProductsController.php

<?php

namespace App\Http\Controllers;

use App\Product;
use Illuminate\Http\Request;

class ProductsController extends Controller {
	/**
	 * Display a listing of the resource.
	 *
	 * @return \Illuminate\Http\Response
	 */
	public function index() {
		$products = Product::latest()->paginate( 5 );

		return view( 'products.index', [ 'products' => $products ] )
			->with( 'i', ( request()->input( 'page', 1 ) - 1 ) * 5 );
	}

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

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

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

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

	/**
	 * Display the specified resource.
	 *
	 * @param \App\Shop $shop
	 *
	 * @return \Illuminate\Http\Response
	 */
	public function show( Product $product ) {
		return view( 'products.show', [ 'product' => $product ] );
	}

	/**
	 * Show the form for editing the specified resource.
	 *
	 * @param \App\Shop $shop
	 *
	 * @return \Illuminate\Http\Response
	 */
	public function edit( Product $product ) {
		return view( 'products.edit', [ 'product' => $product ] );
	}

	/**
	 * Update the specified resource in storage.
	 *
	 * @param \Illuminate\Http\Request $request
	 * @param \App\Shop $shop
	 *
	 * @return \Illuminate\Http\Response
	 */
	public function update( Request $request, Product $product ) {
		$request->validate( [
			'name'       => 'required',
			'price' => 'required',
		] );

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

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

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

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

6. Creating View files

Now we have to add few blade files to present a view of our CRUD shop Application. Note that we will use Bootstrap for the design.

First we will create a layout file which will act as a template for other view files.

resources/views/products/layout.blade.php

<!DOCTYPE html>
<html>
<head>
<title>Laravel 8 CRUD Shop Application with DataTable - Laramatic.com</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.23/css/jquery.dataTables.min.css">
<script type="text/javascript" src="https://cdn.datatables.net/1.10.23/js/jquery.dataTables.min.js"></script>
</head>
<body>

<div class="container">
    <div class="row">
        <div class="col-md-10 offset-1">
            @yield('content')
        </div>
    </div>
</div>
<script type="text/javascript">
    $(document).ready(function () { $('.table').DataTable(); });
</script>
</body>
</html>

resources/views/products/index.blade.php

@extends('products.layout')

@section('content')
    <div class="card mt-5">
        <div class="card-header">
            <h2>Laravel 8 CRUD Shop Example - Laramatic.com</h2>
        </div>
        <div class="card-body">
            <div class="row">
                <div class="col-lg-12 mt-1 mr-1">
                    <div class="float-right">
                        <a class="btn btn-success" href="{{ route('products.create') }}"> Create New Product</a>
                    </div>
                </div>
            </div>
            <div class="row mt-10">
                <div class="col-lg-12">
                    @if ($message = Session::get('success'))
                        <div class="alert alert-success">
                            <p>{{ $message }}</p>
                        </div>
                    @endif
                </div>
                <div class="col-lg-12">
                    <table class="table table-bordered">
                        <thead>
                        <tr>
                            <th>No</th>
                            <th>Name</th>
                            <th>Price</th>
                            <th>Description</th>
                            <th width="280px">Action</th>
                        </tr>
                        </thead>
                        <tbody>
                        @foreach ($products as $product)

                            <tr>
                                <td>{{ ++$i }}</td>
                                <td>{{ $product->name }}</td>
                                <td>{{ $product->price }}</td>
                                <td>{{ \Str::limit($product->description, 50) }}</td>
                                <td>
                                    <form action="{{ route('products.destroy',$product->id) }}" method="POST">

                                        <a class="btn btn-info" href="{{ route('products.show',$product->id) }}">Show</a>

                                        <a class="btn btn-primary" href="{{ route('products.edit',$product->id) }}">Edit</a>

                                        @csrf
                                        @method('DELETE')

                                        <button type="submit" class="btn btn-danger">Delete</button>
                                    </form>
                                </td>
                            </tr>
                        @endforeach
                        </tbody>
                    </table>
                    {!! $products->links() !!}
                </div>
            </div>
        </div>
    </div>
@endsection

resources/views/products/show.blade.php

@extends('products.layout')

@section('content')
    <div class="card mt-5">
        <div class="card-header">
            <h2>Laravel 8 CRUD Shop Example from scratch - Laramatic.com</h2>
        </div>
        <div class="card-body">
            <div class="row">
                <div class="col-lg-12 mt-1 mr-1">
                    <div class="float-right">
                        <a class="btn btn-primary" href="{{ route('products.index') }}"> Back</a>
                    </div>
                </div>
            </div>
            <div class="row mt-2">
                <div class="col-lg-12">
                    @if ($message = Session::get('success'))
                        <div class="alert alert-success">
                            <p>{{ $message }}</p>
                        </div>
                    @endif
                </div>
                <div class="col-lg-12">
                    <div class="row">
                        <div class="col-xs-12 col-sm-12 col-md-12">
                            <div class="form-group">
                                <strong>Name:</strong>
                                {{ $product->name }}
                            </div>
                        </div>
                        <div class="col-xs-12 col-sm-12 col-md-12">
                            <div class="form-group">
                                <strong>Price:</strong>
                                {{ $product->price }}
                            </div>
                        </div>
                        <div class="col-xs-12 col-sm-12 col-md-12">
                            <div class="form-group">
                                <strong>Description:</strong>
                                {{ $product->description }}
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection

resources/views/products/edit.blade.php

@extends('products.layout')

@section('content')
    <div class="card mt-5">
        <div class="card-header">
            <h2>Laravel 8 CRUD Shop Example - Laramatic.com</h2>
        </div>
        <div class="card-body">
            <div class="row">
                <div class="col-lg-12 mt-1 mr-1">
                    <div class="float-right">
                        <a class="btn btn-primary" href="{{ route('products.index') }}"> Back</a>
                    </div>
                </div>
            </div>
            <div class="row mt-2">
                <div class="col-lg-12">
                    @if ($message = Session::get('success'))
                        <div class="alert alert-success">
                            <p>{{ $message }}</p>
                        </div>
                    @endif
                </div>
                <div class="col-lg-12">
                    @if ($errors->any())
                        <div class="alert alert-danger">
                            <strong>Whoops!</strong> There were some problems with your input.<br><br>
                            <ul>
                                @foreach ($errors->all() as $error)
                                    <li>{{ $error }}</li>
                                @endforeach
                            </ul>
                        </div>
                    @endif

                    <form action="{{ route('products.update',$product->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>Name:</strong>
                                    <input type="text" name="name" value="{{ $product->name }}" class="form-control" placeholder="Name">
                                </div>
                            </div>
                            <div class="col-xs-12 col-sm-12 col-md-12">
                                <div class="form-group">
                                    <strong>Price:</strong>
                                    <input type="text" name="price" value="{{ $product->price }}" class="form-control" placeholder="Price">
                                </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">{{ $product->description }}</textarea>
                                </div>
                            </div>
                            <div class="col-xs-12 col-sm-12 col-md-12 text-center">
                                <button type="submit" class="btn btn-success">Submit</button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
@endsection

Now run the following command to run Laravel Shop Application on your local Setup.

php artisan serve

Here is what will appear in your Browser. In just a few minutes you will be able to create full Shop Application with real products.

If you want to read about Laravel Migrations in depth, visit https://laravel.com/docs/8.x/migrations. If you have any questions regarding documentation leave a comment below.