Laravel 7 Tutorial | Build a CRUD application with Laravel 7

Laravel 7 is now released and includes many new features including Laravel Airlock, better routing speed, custom Eloquent casts, Blade component tags, fluent string operations, a new HTTP client, CORS support, and many more features.

In this article we will build a CRUD application with Laravel 7 step by step, a complete guide for beginners to join

Step 1: Laravel 7 Install

Type the following command.

laravel new laravel7crud
I am using Laravel Valet to install Laravel 7, but if you are not using Valet, then also you can create the Laravel 7 project by updating the Composer globally.
composer global update
Now, create a new Laravel project.

➜  sites laravel new laravel7crud
Crafting application...
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Package operations: 93 installs, 0 updates, 0 removals
  - Installing doctrine/inflector (1.3.1): Downloading (100%)
  - Installing doctrine/lexer (1.2.0): Downloading (100%)
  - Installing dragonmantank/cron-expression (v2.3.0): Downloading (100%)         
  - Installing voku/portable-ascii (1.4.9): Downloading (100%)
  - Installing symfony/polyfill-ctype (v1.14.0): Loading from cache
  - Installing phpoption/phpoption (1.7.2): Downloading (100%)
  - Installing vlucas/phpdotenv (v4.1.1): Downloading (100%)
  - Installing symfony/css-selector (v5.0.5): Downloading (100%)
  - Installing tijsverkoyen/css-to-inline-styles (2.2.2): Downloading (100%)      
  - Installing symfony/polyfill-mbstring (v1.14.0): Loading from cache
  - Installing symfony/var-dumper (v5.0.5): Loading from cache
  - Installing symfony/routing (v5.0.5): Downloading (100%)
  - Installing symfony/process (v5.0.5): Downloading (100%)
  - Installing symfony/polyfill-php72 (v1.14.0): Downloading (100%)
  - Installing symfony/polyfill-intl-idn (v1.14.0): Downloading (100%)
  - Installing symfony/mime (v5.0.5): Downloading (100%)
  - Installing symfony/polyfill-php73 (v1.14.0): Loading from cache
  

Now, go inside the laravel7crud folder. You need to install the frontend dependencies for frontend scaffolding using the following command.

cd laravel7crud
npm install

Step 2: Configure the MySQL Database

I have created the MySQL database called laravel7crud and now write the MySQL credentials inside the **.env **file. Before creating the migrations, we need to set up the MySQL database, assuming you know how to create a database using PHPMyAdmin.

My **.env **config for MySQL Database is the following.

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

Please don’t write your username and password other then **.env **file because it is created for putting secret credentials.

Laravel always ships with default migration files, so you able to generate the tables in the database using the following command.

php artisan migrate
If you find an error like: [Illuminate\Database\QueryException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table users add unique users_email_unique(email))

Then you should follow the below steps.
Here what you have to do is, edit your AppServiceProvider.php file, and inside the boot, the method sets a default string length.

use Illuminate\Support\Facades\Schema;

public function boot()
{
    Schema::defaultStringLength(191);
}

Now, you should be able to migrate the tables.

php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (0.06 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (0.02 seconds)

Step 3: Create a model and migration files

We have already set up MySQL database, now let’s look at the database migrations. Migration is used to save the details in the database table, and it’s the properties, so you don’t have to manually generate all the tables by going to a database interface or something like phpmyadmin.

We can create the migrations using artisan with “make: migration” command.
Type the following command to create the model and migration files.

php artisan make:model Corona -m
In laravel, the name of the model has to be singular, and the name of a migration should be the plural so it can automatically find the table name.

It will create the Corna**.php** file and [timestamp]create_coronas_table.php migration file.

Now, write the following code inside [timestamp]create_coronas_table.php file**.**

public function up()
{
        Schema::create('coronas', function (Blueprint $table) {
            $table->id();
            $table->string('country_name');
            $table->string('symptoms');
            $table->integer('cases');
            $table->timestamps();
        });
 }
 

One thing which specifically changes from Laravel 6 to Laravel 7 is that now we explicitly define id() column name, which means it is the primary key and automatically auto-increment sets to 1.
Now, again run the migration using the following command.

php artisan migrate
Migrating: 2020_03_12_105649_create_coronas_table
Migrated:  2020_03_12_105649_create_coronas_table (0.03 seconds)
If you need to reverse the migrations, you can use a migrate**: rollback** command, which will execute the down() function like php artisan migrate:rollback.

Now, add the **fillable **property inside the Corona.php file.

We can specify all the properties to modify the behavior of a model.

We can write the $table property, which is used to determine the name of the table that this model will interact with future operations.

Step 4: Create routes and controller

Now, we need to create a controller.

First, create the **CoronaController **using the following command.

php artisan make:controller CoronaController --resource

Note that we have also added the –resource flag which will define six methods inside the ShowController namely:

  • Index (This function is used for displaying a list of Shows)

  • Create (This function will show the view with a form for creating a Show)

  • Store (This function is used for creating a Show inside the database. Note: create method submits to store method)

  • Show (This function will display a specified Show)

  • Edit (This function will show the form for editing a Show. Form will be filled with the existing Show data)

  • Update (This function is used for updating a Show inside the database. Note: edit submits to update method)

  • Destroy (This function is used for deleting the specified CoronaCase).

Now, inside the **routes >> web.php **file, insert the following line of code.

// web.php

Route::get('/', function () {
    return view('welcome');
});
Route::resource('coronas', 'CoronaController');

Just like — resource flag, laravel has the method called resource() that will generate all the above routes. You can also use the method instead of specifying them individually like above.

Actually, by adding the following code line, we have registered the multiple routes for our app. We can check it using the following command.

php artisan route:list

See the output.

➜ laravel7crud php artisan route:list
±-------±----------±----------------------±----------------±----------------------------------------------±-------------+
| Domain | Method | URI | Name | Action | Middleware |
±-------±----------±----------------------±----------------±----------------------------------------------±-------------+
| | GET|HEAD | / | | Closure | web |
| | GET|HEAD | api/user | | Closure | api,auth:api |
| | GET|HEAD | coronas | coronas.index | App\Http\Controllers\CoronaController@index | web |
| | POST | coronas | coronas.store | App\Http\Controllers\CoronaController@store | web |
| | GET|HEAD | coronas/create | coronas.create | App\Http\Controllers\CoronaController@create | web |
| | GET|HEAD | coronas/{corona} | coronas.show | App\Http\Controllers\CoronaController@show | web |
| | PUT|PATCH | coronas/{corona} | coronas.update | App\Http\Controllers\CoronaController@update | web |
| | DELETE | coronas/{corona} | coronas.destroy | App\Http\Controllers\CoronaController@destroy | web |
| | GET|HEAD | coronas/{corona}/edit | coronas.edit | App\Http\Controllers\CoronaController@edit | web |
±-------±----------±----------------------±----------------±----------------------------------------------±-------------+

Step 5: Configure Bootstrap 4

The Bootstrap and Vue scaffolding provided by Laravel is located in the laravel/ui Composer package, which may be installed using Composer.

composer require laravel/ui

Once the laravel/ui package has been installed, you may install the frontend scaffolding using the ui Artisan command.

php artisan ui bootstrap

See the output.

php artisan ui bootstrap
Bootstrap scaffolding installed successfully.
Please run "npm install && npm run dev" to compile your fresh scaffolding.

Step 6: Create the views

Inside the** views **directory, we also need to create a layout file.

So, we will create the file inside the **views **directory called **layout.blade.php. **

Add the following code in the **layout.blade.php **file.


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Laravel 7 CRUD Example</title>
  <link href="{{ asset('css/app.css') }}" rel="stylesheet" type="text/css" />
</head>
<body>
  <div class="container">
    @yield('content')
  </div>
  <script src="{{ asset('js/app.js') }}" type="text/js"></script>
</body>
</html>


Inside the **resources >> views **folder, create the following three-view files.

  • create.blade.php

  • edit.blade.php

  • index.blade.php

Inside the **create.blade.php **file, write the following code.



@extends('layout')

@section('content')
<style>
  .uper {
    margin-top: 40px;
  }
</style>
<div class="card uper">
  <div class="card-header">
    Add Corona Virus Data
  </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><br />
    @endif
      <form method="post" action="{{ route('coronas.store') }}">
          <div class="form-group">
              @csrf
              <label for="country_name">Country Name:</label>
              <input type="text" class="form-control" name="country_name"/>
          </div>
          <div class="form-group">
              <label for="symptoms">Symptoms :</label>
              <textarea rows="5" columns="5" class="form-control" name="symptoms"></textarea>
          </div>
          <div class="form-group">
              <label for="cases">Cases :</label>
              <input type="text" class="form-control" name="cases"/>
          </div>
          <button type="submit" class="btn btn-primary">Add Data</button>
      </form>
  </div>
</div>
@endsection


Okay, now we need to open the **Corona****Controller.php **file, and on the create() method, we need to return the view, and that is the **create.blade.php **file.

// CoronaController.php

public function create()
{
   return view('create');
}

Go to a http://localhost:8000/coronas/create or http://laravel7crud.test/coronas/create

You will see something like the following.

This is image title

Step 7: Add Validation rules and save data

In this step, we will add Laravel form Validation.

Now, add the CoronaController.php is that import the namespace of the Corona model inside the CoronaController**.php** file.


<?php

// CoronaController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Corona;


Now, write the following code inside the CoronaController.php file’s store() function.

// CoronaController.php

public function store(Request $request)
{
        $validatedData = $request->validate([
            'country_name' => 'required|max:255',
            'symptoms' => 'required',
            'cases' => 'required|numeric',
        ]);
        $show = Corona::create($validatedData);

        return redirect('/coronas')->with('success', 'Corona Case is successfully saved');
}

Here, what we have done is, first check for all four fields of the form.

If the incoming data fail any of the rules, then it will directly go to the form with the error messages.

The store() method has a $request object as a parameter which will be used to access form data.

The first thing you want to do is validate the form of data.

We can use the $request->validate() function for validation, which will receive the array of validation rules.

Validation rules[] is the associative array.

Key will be the field_name and value with being the validation rules.

The second parameter is an optional array for custom validation messages.

Rules are separated with a pipe sign “|.” We are using the most basic validation rules.

If the validation fails, then it will redirect back to the form page with error messages. After the validation, we are creating the new case and save that case in the database.

We need to loop through that error messages inside the **create.blade.php **file, which we have already done it.

If you leave all the form fields empty, then you will find the error message like this image.

This is image title

Now, if you fill the form fields correctly, then it will create a new row in the database. I have created a new Case.

This is image title

Step 8: Display the data

Now, we need to write the CoronaController’s index function to return the index view with data fetched from the database. Write the following code inside the index() function.

// CoronaController.php

public function index()
{
        $coronacases = Corona::all();

        return view('index', compact('coronacases'));
}

Okay, now create a file called **index.blade.php **inside the views folder and add the following code.


@extends('layout')

@section('content')
<style>
  .uper {
    margin-top: 40px;
  }
</style>
<div class="uper">
  @if(session()->get('success'))
    <div class="alert alert-success">
      {{ session()->get('success') }}  
    </div><br />
  @endif
  <table class="table table-striped">
    <thead>
        <tr>
          <td>ID</td>
          <td>Country Name</td>
          <td>Symptoms</td>
          <td>Cases</td>
          <td colspan="2">Action</td>
        </tr>
    </thead>
    <tbody>
        @foreach($coronacases as $case)
        <tr>
            <td>{{$case->id}}</td>
            <td>{{$case->country_name}}</td>
            <td>{{$case->symptoms}}</td>
            <td>{{$case->cases}}</td>
            <td><a href="{{ route('coronas.edit', $case->id)}}" class="btn btn-primary">Edit</a></td>
            <td>
                <form action="{{ route('coronas.destroy', $case->id)}}" method="post">
                  @csrf
                  @method('DELETE')
                  <button class="btn btn-danger" type="submit">Delete</button>
                </form>
            </td>
        </tr>
        @endforeach
    </tbody>
  </table>
<div>
@endsection


Here, we have looped through the coronacases’ array and display the data in a table format.

Also, we have added two buttons for **edit **and **delete **operation.

This is image title

Step 9: Create Edit and Update Operation

First, we need to add the following code inside the CoronaController.php file’s edit function.

// CoronaController.php

public function edit($id)
{
        $coronacase = Corona::findOrFail($id);

        return view('edit', compact('coronacase'));
}

Now, create the new file inside the views folder called **edit.blade.php **and add the following code.



@extends('layout')

@section('content')
<style>
  .uper {
    margin-top: 40px;
  }
</style>
<div class="card uper">
  <div class="card-header">
    Edit Corona Virus Data
  </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><br />
    @endif
      <form method="post" action="{{ route('coronas.update', $coronacase->id ) }}">
          <div class="form-group">
              @csrf
              @method('PATCH')
              <label for="country_name">Country Name:</label>
              <input type="text" class="form-control" name="country_name" value="{{ $coronacase->country_name }}"/>
          </div>
          <div class="form-group">
              <label for="symptoms">Symptoms :</label>
              <textarea rows="5" columns="5" class="form-control" name="symptoms">{{ $coronacase->symptoms }}</textarea>
          </div>
          <div class="form-group">
              <label for="cases">Cases :</label>
              <input type="text" class="form-control" name="cases" value="{{ $coronacase->cases }}"/>
          </div>
          <button type="submit" class="btn btn-primary">Update Data</button>
      </form>
  </div>
</div>
@endsection


Go to any edit page of the listing data. Like, go to the: **http://laravel7crud.test/coronas/1/edit **or whatever URL of yours.

Now, add the following code inside the CoronaController’s update() function.

// CoronaController.php

public function update(Request $request, $id)
{
        $validatedData = $request->validate([
            'country_name' => 'required|max:255',
            'symptoms' => 'required',
            'cases' => 'required|numeric',
        ]);
        Corona::whereId($id)->update($validatedData);

        return redirect('/coronas')->with('success', 'Corona Case Data is successfully updated');
}

So now, you can update all the data into the database.

Step 10: Create Delete Functionality

Write the following code inside the CoronaController’s destroy function.

// CoronaController.php

public function destroy($id)
{
        $coronacase = Corona::findOrFail($id);
        $coronacase->delete();

        return redirect('/coronas')->with('success', 'Corona Case Data is successfully deleted');
}

Go to the URL: http://laravel7crud.test/coronas and try to remove the Corona Case data.

You can see that you have successfully removed the case.

So, our complete CoronaController.php code looks like below.




<?php

// CoronaController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Corona;

class CoronaController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $coronacases = Corona::all();

        return view('index', compact('coronacases'));
    }

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

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $validatedData = $request->validate([
            'country_name' => 'required|max:255',
            'symptoms' => 'required',
            'cases' => 'required|numeric',
        ]);
        $show = Corona::create($validatedData);
   
        return redirect('/coronas')->with('success', 'Corona Case is successfully saved');
    }

    /**
     * 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)
    {
        $coronacase = Corona::findOrFail($id);

        return view('edit', compact('coronacase'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $validatedData = $request->validate([
            'country_name' => 'required|max:255',
            'symptoms' => 'required',
            'cases' => 'required|numeric',
        ]);
        Corona::whereId($id)->update($validatedData);

        return redirect('/coronas')->with('success', 'Corona Case Data is successfully updated');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $coronacase = Corona::findOrFail($id);
        $coronacase->delete();

        return redirect('/coronas')->with('success', 'Corona Case Data is successfully deleted');
    }
}


So, we have completed a Laravel 7 CRUD operations example from scratch.

If you are interested in the FrontEnd Javascript framework like Vue with Laravel or Angular with Laravel, then check out the guides like Vue Laravel CRUD example and Angular Laravel Tutorial Example.

I have put the whole crud operation code on Github so you can check it out as well.

GITHUB CODE

#laravel #php #laravel7 #webdev

 Laravel 7 Tutorial  | Build a CRUD application with  Laravel 7
39.50 GEEK