At a beginner level, it is always recommended to start with a very basic in any technology to learn. The CRUD application is the first way to have an understanding of database connectivity and application synchronization. Laravel 10 is released and we already discussed the new features of Laravel 10. Today, we will start with a very basic CRUD application in Laravel 10. So that, we can see how to install and work with Laravel 10. Further, we will move out to the more advanced tutorials with examples in this series. So, let’s start with the first application in Laravel 10.
Prerequisites
We are going to create a new application in Laravel 10. Hence, to have this, you will require the below configurations and tools.
- PHP >=8.1
- Composer
- Apache/Nginx Server
- VS Code Editor (Optional)
- MySQL (version > 5)
I will be using composer to create a new application in Laravel 10. However, if you are a Mac user, you can go with the Laravel installer as well.
If you don’t feel comfortable reading this article then you can watch our YouTube video for the Laravel CRUD Application from scratch.
Install Laravel 10 For a CRUD Application
For installing a Laravel application, look at the terminal and hit the below command.
composer create-project --prefer-dist laravel/laravel todo-app
It will take a couple of seconds to have a brand new Laravel 10 application.
Once Laravel 10 has been installed, you can open the project in the editor. Now, run the application using the below command.
php artisan serve
Now, navigate to the browser and visit localhost:8000
So, the Laravel 10 application is running properly. Now, in the next step, we will setup database for our project.
Create and Configure a Database For CRUD Application
I will be managing the database with phpMyAdmin. Hence, I have created a database and now going to configure the database credentials in the Laravel 10 application.
CREATE DATABASE laravel_todo;
For database configuration in the Laravel application, you need to navigate to the root folder of the project. Now, look for the .env file, and under the Database section, add the below configurations.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_todo
DB_USERNAME=root
DB_PASSWORD=root
After the database configuration, we need to create the model, migration, and controller for the todo app.
Create a Model, Migration, and Controller in Laravel 10
You can create a model, migration, and controller in one go using the below command.
php artisan make:model Todo -mc
Or either you can follow the command prompt for the option as shown below.
I have created the resource controller for the Todo app.
Now, in the next step, you need to write a schema for the table(s) in the created migration.
Add Migration For Todo App
For creating a database schema, just look at the migrations folder. Now, find the created migration file.
Next, add the schema as shown below.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('todos', function (Blueprint $table) {
$table->id();
$table->string('title')->nullable();
$table->string('description')->nullable();
$table->boolean('is_completed')->default(false);
$table->boolean('is_deleted')->default(false);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('todos');
}
};
After creating the migration, you need to add a fillable property in its model. So, navigate to the Todo.php model. Then add the below snippet there.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Todo extends Model
{
use HasFactory;
protected $fillable = [
'title',
'description',
'is_completed',
'is_deleted'
];
}
Next, you need to migrate the schema. So that it will dump out the table architecture in the database. In order to do that, you will require to run the below command.
php artisan migrate
The above command will migrate the tables as shown below.
After the migration, we will start the functional part of the CRUD application in Laravel 10.
Functionality For CRUD Application in Laravel 10
We are creating a Todo app. Hence, we need to write the below snippets in the TodoController.
<?php
namespace App\Http\Controllers;
use App\Models\Todo;
use Illuminate\Http\Request;
class TodoController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
try {
$todos = Todo::all();
return view('index', compact('todos'));
} catch (Exception $e) {
Log::error($e->getMessage());
}
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
return view('create');
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
try {
$todo = Todo::create([
'title' => $request->title,
'description' => $request->description
]);
if ($todo) {
return redirect()->route('todos.index')->with('success', 'Todo list created successfully!');
}
return back()->with('error', 'Unable to create todo. Please try again.');
} catch (Exception $e) {
Log::error($e->getMessage());
}
}
/**
* Display the specified resource.
*/
public function show(Todo $todo)
{
return view('show', compact('todo'));
}
/**
* Show the form for editing the specified resource.
*/
public function edit(Todo $todo)
{
return view('edit', compact('todo'));
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, Todo $todo)
{
try {
$todo['title'] = $request->title;
$todo['description'] = $request->description;
$todo->save();
return redirect()->route('todos.index')->with('success', 'Todo list updated successfully!');
} catch (Exception $e) {
Log::error($e->getMessage());
}
}
/**
* Remove the specified resource from storage.
*/
public function destroy(Todo $todo)
{
try {
if ($todo) {
$todo->delete();
return redirect()->route('todos.index')->with('success', 'Todo list deleted successfully!');
}
return back()->with('error', 'Todo list not found!');
} catch (Exception $e) {
Log::error($e->getMessage());
}
}
}
After adding the above functionalities, we need to create a couple of views respectively.
Create Views For Todos App
For the todos application, we will be creating the following views.
- master.blade.php
- index.blade.php
- create.blade.php
- show.blade.php
- edit.blade.php
Now, let’s start by adding the snippets in these views one by one. Start with master blade.
<!doctype html>
<html lang="en">
<head>
<title>Laravel 10 CRUD Application</title>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS v5.2.1 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-iYQeCzEYFbKjA/T2uDLTpkwGzCiq6soy8tYaI1GyVh/UjpbCx/TYkiZhlZB6+fzT" crossorigin="anonymous">
</head>
<body>
<div class="container">
@yield('content')
</div>
<!-- Jquery CDN -->
<script src="https://code.jquery.com/jquery-3.7.0.min.js"
integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g=" crossorigin="anonymous"></script>
<!-- Bootstrap JavaScript Libraries -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js"
integrity="sha384-oBqDVmMz9ATKxIep9tiCxS/Z9fNfEXiDAYTujMAeBAsjFuCZSmKbSSUnQlmh/jp3" crossorigin="anonymous">
</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/js/bootstrap.min.js"
integrity="sha384-7VPbUDkoPSGFnVtYi0QogXtr74QeVeeIs99Qfg5YCF+TidwNdjvaKZX19NZ/e6oz" crossorigin="anonymous">
</script>
</body>
</html>
Then next, add the snippet in the index blade.
@extends('master')
@section('content')
@section('title') | Todos Listing @endsection
<div class="row">
<div class="col-xl-12 text-end">
<a href="{{ route('todos.create') }}" class="btn btn-primary"> Add Todo </a>
</div>
</div>
<div class="card my-3">
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="check-circle-fill" fill="currentColor" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"/>
</symbol>
<symbol id="exclamation-triangle-fill" fill="currentColor" viewBox="0 0 16 16">
<path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/>
</symbol>
</svg>
@if (Session::has('success'))
<div class="alert alert-success alert-dismissible d-flex align-items-center" role="alert">
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Success:"><use xlink:href="#check-circle-fill"/></svg>
<div>
{{ Session::get('success') }} <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
</div>
@elseif (Session::has('error'))
<div class="alert alert-danger d-flex alert-dismissible align-items-center" role="alert">
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Danger:"><use xlink:href="#exclamation-triangle-fill"/></svg>
<div>
{{ Session::get('error') }} <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
</div>
@endif
<table class="table table-striped">
<thead class="bg-secondary text-light">
<tr >
<th>Id</th>
<th width="20%">Title</th>
<th width="45%">Description</th>
<th width="15%">Completed</th>
<th width="20%">Action</th>
<tr>
</thead>
<tbody>
@forelse ($todos as $todo)
<tr>
<td>{{ $todo->id }}</td>
<td>{{ $todo->title }}</td>
<td>{{ $todo->description }}</td>
<td>{{ $todo->is_completed == 1 ? 'Yes' : 'No' }}</td>
<td>
<form action="{{ route('todos.destroy', $todo->id) }}" method="post">
@csrf
<a href="{{ route('todos.show', $todo->id) }}" title="View" class="btn btn-sm btn-info">
View
</a>
<a href="{{ route('todos.edit', $todo->id) }}" title="Edit" class="btn btn-sm btn-success">
Edit </a>
@method('DELETE')
<button type="submit" onclick="return confirm('Are you sure?');" title="Delete" class="btn btn-sm btn-danger"> Delete </button>
</form>
</td>
</tr>
@empty
<tr>
<td colspan="4">
<p class="text-danger text-center fw-bold"> No todos found! </p>
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
@endsection
Next, we will have a view to create a todo list. So, add the below snippet for that.
@extends('master')
@section('content')
@section('title') | Create Todo @endsection
<div class="row">
<div class="col-xl-6 col-lg-8 mx-auto">
<form action="{{ route('todos.store') }}" method="post">
@csrf
<div class="card">
<div class="card-header">
<h5 class="card-title"> Create Todo </h5>
</div>
<div class="card-body">
<div class="form-group my-3">
<label for="title"> Title </label>
<input type="text" required name="title" id="title" class="form-control" placeholder="Title" />
</div>
<div class="form-group my-3">
<label for="description"> Description </label>
<textarea name="description" required id="description" class="form-control" placeholder="Description"></textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-success"> Save </button>
</div>
</div>
</div>
</form>
</div>
</div>
@endsection
Similarly, we have a separate view to display the single todo.
@extends('master')
@section('content')
@section('title') | View Todo @endsection
<div class="row">
<div class="col-xl-6 col-lg-8 mx-auto">
<div class="card">
<div class="card-header">
<h5 class="card-title"> View Todo </h5>
</div>
<div class="card-body">
<div class="form-group my-3">
<label for="title"> Title </label>
<input type="text" readonly disabled class="form-control" value="{{ $todo->title ?? '' }}" />
</div>
<div class="form-group my-3">
<label for="description"> Description </label>
<textarea readonly disabled class="form-control" placeholder="Description">{{ $todo->description ?? '' }}</textarea>
</div>
<div class="form-group my-3">
<label for="description"> Completed </label>
<input type="text" readonly disabled class="form-control" value="{{ $todo->is_completed == 1 ? 'Yes' : 'No' }}" />
</div>
<div class="form-group">
<a href="{{ route('todos.index') }}" class="btn btn-success"> Back </a>
</div>
</div>
</div>
</div>
</div>
@endsection
Next, we have edit blade file to update the todo.
@extends('master')
@section('content')
@section('title') | Update Todo @endsection
<div class="row">
<div class="col-xl-6 col-lg-8 mx-auto">
<form action="{{ route('todos.update', $todo->id) }}" method="post">
@csrf
@method('PUT')
<div class="card">
<div class="card-header">
<h5 class="card-title"> Update Todo </h5>
</div>
<div class="card-body">
<div class="form-group my-3">
<label for="title"> Title </label>
<input type="text" name="title" required id="title" class="form-control" placeholder="Title" value="{{ $todo ? $todo->title : '' }}" />
</div>
<div class="form-group my-3">
<label for="description"> Description </label>
<textarea name="description" required id="description" class="form-control" placeholder="Description">{{ $todo ? $todo->description : '' }}</textarea>
</div>
<div class="form-group my-3">
<label for="completed"> Completed </label>
<select class="form-control" name="completed" id="completed">
<option value="1" {{ $todo->is_completed == 1 ? 'selected' : '' }}> Yes </option>
<option value="0" {{ $todo->is_completed == 0 ? 'selected' : '' }}> No </option>
</select>
</div>
<div class="form-group">
<button type="submit" class="btn btn-success"> Update </button>
</div>
</div>
</div>
</form>
</div>
</div>
@endsection
That’s it, we are done with the functionality part.
But, in order to run the todo application, we missed something. That is the route.
Add Route For CRUD Application in Laravel 10
For adding the route for this CRUD application (Todo app), navigate to the web.php file. Then add the below routes.
<?php
use App\Http\Controllers\TodoController;
use Illuminate\Support\Facades\Route;
Route::resource('todos', TodoController::class);
Now, it’s time to check the result. Hence, run the application in the browser and check for the results.
Check Results of CRUD Application in Laravel 10
Initially, we won’t have any Todo list. So, start adding the todo list.
After adding the Todo list, save it.
We have the View option to check the Todo details.
You can update the Todo list by clicking on the edit option.
That’s it for the post of CRUD Application in Laravel 10.
Final Words
As of result, we created a basic Todo app by using CRUD operations in Laravel 10. You can extend this Todo app further as per your need. This was just a demonstration for beginners who wants to start Laravel 10 directly without having prior knowledge of it. I hope this post will be helpful to you.
Chris Alex says
Great explanation for beginners.