Laravel CRUD system : Part one (Retrieving data)

 

Hi they, in our previous tutorial we learn about the basic of laravel, I believe by now you know what laravel is, if you missed that series click here to check it out. In this series we will begin build our CRUD system. CRUD simply stands for;

  • C = Create
  • R= Read
  • U = Update
  • D = Delete

Before we begin it is good we know what we are building that is where planning comes in. In this tutorial we will be building a product store called “estore”.
A simple application to create, store, update and delete product information. Before now I believe you know how to install laravel.
Let’s get started!


Setup Laravel

Open your terminal application and switch into the directory you want your project to be and type the below command.


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


Database Setup
Before we setup our database configuration we will need to first create our database. Create a new database called estore. Open your terminal and type the below command to create your database.


mysql -u root -p
mysql> create database estore;
mysql> exit

Next we need to configure our .env file


DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=estore
DB_USERNAME=root
DB_PASSWORD=


Authentication Scaffolding setup
To install the UI composer package we run the below command:


composer install laravel/ui

After installing this we will need to run the following to generate routes, controllers, views, and other files necessary for auth:


php artisan ui bootstrap --auth


Next, we need to compile our CSS UI with the following:


npm install

To build dev assets use below command


npm run dev


Let now drive into the main business.  Definitely our application is going to need a database table, so we will start by creating our database base tables. 


Setting Up Migration and Model

We earlier created the database (estore) and configured the database by adding the credentials in the .env file. Now, we are going to create the migration by adding the data properties in the MySQL table. So we will create a Model and Migration file to create the migrations. We are going to create a table called products to store our products so head back to your terminal to hit up the command below:


php artisan make:model Models/Products –m


This command will create a model and a migration file for us.
Our migration files is in the database/migrations folder.


Migration is a Laravel core class that is used for database version control. Migration class provides two functions up() and down(). up() function executes when migration runs. down() function undo the up() function and runs when we rollback last migration or reset the database.


We will add the schema inside our migration file. Our schema will have the following fields; product_id, product_name, product_image, product_details, price.
 So open the migration file go to database > migrations > timestamp_create_products_table.php file, and add the following schema inside of it.


<?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->increments('product_id');
            $table->string('product_name');
            $table->string('product_image');
            $table->text('product_details');
            $table->double('price');
            $table->timestamps();
        });
    }

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


If you notice there are two types of functions inside the migration files:
The up() function allows creating/updating tables, columns, and indexes.
The down() function allows reversing an operation done by up method.


Next, we will add the $fillable property in the Products model, go to app > Models > Products.php file and add the given below code.


<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Products extends Model
{
    protected $fillable = ['product_name', 'product_image', 'product_details', 'price'];
}


Fillable property is used inside the model to determine which data types or fields are mass-assignable in the database table.


The next step is for us to run migration command, head up to your terminal and type the bellow command to create the table in the database:


php artisan migrate


Next we need to create Seeders to populate our database with dummy data.


Creating a Seeder
Laravel includes a simple method of seeding your database with test data using seed classes. All seed classes are stored in the database/seeds directory.


To create seeders, we use the make:seeder Artisan command. All seeders generated will be placed in the database/seeds directory.


php artisan make:seeder ProductsSeeder


Generated seeders will contain one method: run. You may insert data into your database in this method. Open your product seeder and modify with the following codes


<?php

use Illuminate\Database\Seeder;
use Carbon\Carbon;

class ProductsSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        for ($i=0; $i < 10; $i++) {
            DB::table('products')->insert([
              'product_name' => 'Tecno Pop3',
              'product_image' => 'default-image.png',
              'product_details' => 'Lorem ipsum dolor sit amet consectetur adipisicing elit.Tenetur voluptatem quaerat eveniet numquam eligendi corporis, inventore illo laudantium perspiciatis doloribus mollitia, minus id fugiat distinctio sequi libero vero iure doloremque!',
              'price' => '27000',
              'created_at' => Carbon::now(),
            ]);
        }
    }
}



Once you're done writing the seeders, use the db:seed command. This will run DatabaseSeeder's run function. This will populate the database with the dummy data. In the code above we loop the product so that we can have 10 dummy data in our database.


But before running the seeder command let register our products seeder into the DatabaseSeeder class. Open the Database\Seeder and modify with the code below.

<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
    // $this->call(UserSeeder::class);
    $this->call(ProductsSeeder::class);
}
}


Finally run the seeder command to populate the database. 


php artisan db:seed

 
Route and Views
Before we start modifying our Routes, let create our views first. Create a new folder under view called pages. Then create the following files into the pages folder;

  • index.blade.php
  • create.blade.php
  • edit.blade.php
  • show.blade.php

 

Now we will use the

  • index.blade.php to display all our products.
  • create.blade.php to post new product using form,
  •  edit.blade.php to editing our product using form and
  • show.blade.php to show details of a single product.

We will code this views letter.


Configuring Routes
 Head over to routes > web.php file, and add/modify the code with the code
 

<?php

use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| 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!
|
*/

// Return products on the index page
Route::get('/', 'ProductsController@index')->name('index');

//create all resource controller function routes
Route::resource('product', 'ProductsController');

Auth::routes();

// Route::get('/home', 'HomeController@index')->name('home');



Routes for all the resource controller functions are created by Laravel automatically. To link them up with your link your pages open the cmd and type the command below to see them.


php artisan route:list


Create Controller

Next, we are going to generate ProductsController, to do this run the below command;


php artisan make:controller ProductsController --resource

 
The above command will generate our ProductsController file in this path app/Http/Controllers/ProductsController.php. By default, there are seven methods defined in it, which are as follows:

  • index() => shows all products list
  • create() => creates a product using a form
  • store() => creates a product in the database
  • show() => shows a specific product
  • edit() => updates the product data using a form
  • update() => updates the product data using a form
  • destroy() => removes a particular product

Next step is for us to start writing the code in ProductsController.php file to initialize the CRUD. For the series we will take the index() function only.
Modify the index() with the code below;


<?php

namespace App\Http\Controllers;
use App\Models\Products;


use Illuminate\Http\Request;

class ProductsController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $product = Products::orderBy('updated_at', 'desc')->paginate(10);
        return view('pages.index', compact('product'));
    }

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

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($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)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }
}


We are now going back to the views.


Views in Laravel with Blade Templates
Next, we have to build the views for our product CRUD app with blade files. Head back to the pages/files we created before. Let start with the app.blade.php
Add the following code in the app.blade.php template. 


<!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>{{ config('app.name', 'eStore') }} - @yield('title')
</title>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">

    {{-- My styles --}}
    <link href="{{ asset('css/main.css') }}" rel="stylesheet">
</head>
<body>
    <div id="app">
        <main class="py-4">
            @yield('content')
        </main>
    </div>
</body>
</html>


In the code above I have imported my customize style called main.css   let create this file, head to public/css and create a css file called main.css add the following style to it;


h3.h3 {
    text-align: center;
    margin: 1em;
    text-transform: capitalize;
    font-size: 1.7em;
}

.product-grid6,
.product-grid6 .product-image6 {
    overflow: hidden;
}
.product-grid6 {
    font-family: "Open Sans", sans-serif;
    text-align: center;
    position: relative;
    transition: all 0.5s ease 0s;
}
.product-grid6:hover {
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
}
.product-grid6 .product-image6 a {
    display: block;
}
.product-grid6 .product-image6 img {
    width: 100%;
    height: auto;
    transition: all 0.5s ease 0s;
}
.product-grid6:hover .product-image6 img {
    transform: scale(1.1);
}
.product-grid6 .product-content {
    padding: 12px 12px 15px;
    transition: all 0.5s ease 0s;
}
.product-grid6:hover .product-content {
    /* opacity: 0; */
    border: solid whitesmoke 1px;
}
.product-grid6 .title {
    font-size: 20px;
    font-weight: 600;
    text-transform: capitalize;
    margin: 0 0 10px;
    transition: all 0.3s ease 0s;
}
.product-grid6 .title a {
    color: #000;
}
.product-grid6 .title a:hover {
    color: #2e86de;
}
.product-grid6 .price {
    font-size: 18px;
    font-weight: 600;
    color: #2e86de;
}
.product-grid6 .price span {
    color: #999;
    font-size: 15px;
    font-weight: 400;
    text-decoration: line-through;
    margin-left: 7px;
    display: inline-block;
}

@media only screen and (max-width: 990px) {
    .product-grid6 {
        margin-bottom: 30px;
    }
}


Next, add the following code in the resources/views/index.blade.php file.


@extends('layouts.app')

@section('title')
    Products
@endsection

@section('content')

<div class="container">
    <h3 class="h3">All Products</h3>
    @if (isset($product) && count($product) > 0)

    <div class="row">
        @foreach($product as $products)
        <div class="col-md-3 col-sm-6">
            <div class="product-grid6">
                <div class="product-image6">
                    <a href="#">
                        <img class="pic-1" src="{{ $products ?                     asset('images/'.$products->product_image) : 'link_to_default_image' }}">
                    </a>
                </div>
                <div class="product-content">
                    <h3 class="title"><a href="#">{{$products->product_name}}</a></h3>
                    <div class="price">N{{$products->price}}
                    </div>
                </div>
            </div>
        </div>
        @endforeach
      {{-- pagination --}}
      {{ $product->appends(Request::all())->links() }}
        @else
        <div class="card">
            <div class="card-body">
                <h4 class="card-title">Nothing to show!</h4>
                <p class="card-description">All products out of stock</p>
                
            </div>
        </div>
        @endif
    </div>
</div>
<hr>

@endsection

 
Next is for us to copy our default image to public > images

 
Create a folder called images under the public folder and copy an image to the folder and rename it to default-image.png

 
With this we have successfully created the retrieving part of our crud system. Serve the app with the command 

php artisan serve

 
and preview it on your browser @ localhost:8000 or as your case maybe.
That is the end for this series, in our next series we perform other CRUD operations like update, delete, show single product and brush up the design.
Source code on Github eStore

Post a Comment

2 Comments