Laravel has released Laravel 7 on the 3rd of March 2020. Laravel 6.x was released on the LTS (Long Term Support) mode. In every release of Laravel version, it adds some new features and try to fix the previous bugs. Laravel major framework releases are released every six months (February and August), while minor and patch releases may be released as often as every week. Minor and patch releases should never contain breaking changes. So, before starting the Laravel 7 CRUD Tutorial, we will see the new features in Laravel 7.
New Features and Improvements in Laravel 7
According to the official documents of Laravel, Laravel 7 has added the following features –
- Sanctum,
- Routing speed improvements,
- Custom Eloquent casts,
- Blade component tags,
- Fluent string operations,
- A developer-focused HTTP client,
- First-party CORS support
- Improved scoping for route model binding
- Stub customization
- Database queue improvements,
- Multiple mail drivers,
- Query-time casts,
- A new artisan test command and
- A variety of other bug fixes and usability improvements.
In this post, I am not going to explain each and every feature of Laravel 7. I will try to show you with an example in our upcoming Laravel 7 posts. So, for now, let’s come to the Laravel 7 CRUD application tutorial. Here, I will start with a new setup of Laravel 7.
How to Resize Image in Laravel 6 Before Upload
Prerequisites
For creating a new application with Laravel 7 please make sure your requirements meet the followings –
- PHP >= 7.2.5
- MySQL > 5
- Apache/Nginx Server
- VS Code Editor (Optional)
- Composer
You can check the PHP version of your system by hitting the below command in the command prompt.
php -v
I have the PHP version 7.4.3. If you have the PHP version below than 7.2.5 then it is highly recommended to upgrade first. Similarly, you can check the MySQL version.
Create a New Project in Laravel 7
For creating a new project in Laravel 7, I am using Composer. We will install Laravel 7 with the help of the composer.
composer create-project --prefer-dist laravel/laravel laravel-7-crud
It will take a few minutes to install the Laravel 7 libraries. So, just hold on while it completes.
Create and Configure Database
After creating the project, we will create a new database inside the MySQL database. So, just create a new database by hitting the below command.
CREATE DATABASE laravel7_crud
Now, we will configure the database for the Laravel 7 CRUD application that we have created. So for the database configuration, you will have to move to the .env file inside the project.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel7_crud
DB_USERNAME=root
DB_PASSWORD=root
Here, I have updated the database credentials, you will have to replace your own database user and password if you have set.
Create Model and Migration in Laravel 7
According to the MVC architecture, Laravel 7 provides the Eloquent relationship among the tables. Which defines the relationship between two or more tables. The model associated with the table. So, every single operation with the database can be handled using the Model. So, let’s create a Model for our application.
php artisan make:model Post --migration
The above command will create a Model named Post along with migration. The migration will ensure the schema of the table. So you can find the migration inside the database->migrations folder.
Create a Schema of Posts Table
Just open the create_posts_table and replace the schema with the below code.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string("title")->nullable();
$table->string("slug")->nullable();
$table->string("category")->nullable();
$table->string("description")->nullable();
$table->integer("published")->default(1);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}
After creating the above migration, I will be migrating the table inside the database.
Add Fillable Data in the Model
We will have to specify the fields which will be going to insert into the table. So, here I have defined the following fields for which I will be creating a form and from that form, I will be passing the value to the controller.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
// mass assignment
protected $fillable = [
"title", "slug", "category", "description"
];
}
Migrate Table in Laravel 7
In Laravel 7, we can create the tables by migrating the migrations of the table. Hence, we will run the migration, it will generate the table with the defined schema.
php artisan migrate
Create Controller
For adding the functionality of CRUD we will require to create a Controller. The controller will allow us to coordinate with the Model. Then the model will access the database. Laravel provides the predefined functions for the CRUD (Create, Read, Update and Delete). This is called the resource. So, we can create the controller with the resource.
php artisan make:controller PostController --resource
The above command will create a controller named PostController along with the required functions for the CRUD operation.
So, simply replace the below code with your controller’s code.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use App\Post;
class PostController extends Controller {
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index() {
$posts = Post::all();
return view("index", compact("posts"));
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create() {
return view('create-post');
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request) {
$validator = $request->validate([
"title" => "required",
"category" => "required",
"description" => "required"
]);
$title = $request->title;
$slug = str_replace(" ", "-", strtolower($title));
$slug = preg_replace("[/A-Za-z0-9/]", "-", $slug);
$slug = preg_replace("[/*&%/]", "-", $slug);
$postData = array(
"title" => $request->title,
"slug" => $slug,
"category" => $request->category,
"description" => $request->description,
);
$post = Post::create($postData);
if(!is_null($post)) {
return back()->with("success", "Post published successfully");
}
else {
return back()->with("error", "Whoops! failed to publish the post");
}
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id) {
$post = Post::find($id);
return view("show-post", compact("post"));
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id) {
$post = Post::find($id);
return view("edit-post", compact("post"));
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id) {
$validator = $request->validate([
"title" => "required",
"category" => "required",
"description" => "required"
]);
$title = $request->title;
$slug = str_replace(" ", "-", strtolower($title));
$slug = preg_replace("[/A-Za-z0-9/]", "-", $slug);
$slug = preg_replace("[/*&%/]", "-", $slug);
$postData = array(
"title" => $request->title,
"slug" => $slug,
"category" => $request->category,
"description" => $request->description
);
$post = Post::find($id)->update($postData);
if($post == 1) {
return back()->with("success", "Post updated successfully");
}
else {
return back()->with("failed", "Whoops! Failed to update");
}
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id) {
$post = Post::find($id)->delete();
if($post == 1) {
return back()->with("success", "Post deleted successfully");
}
else{
return back()->with("failed", "Failed to delete post");
}
}
}
In the above snippets, I have created the functionalities for the CRUD application. Now, according to this perspective, we will have to create some views where we will create the form and inputs.
Create Views
According to this application, we will be requiring to create the following views.
- master-layout.blade.php
- create-post.blade.php
- show-post.blade.php
- edit-post-blade.php
- index.blade.php
In the master layout blade file, I will define the global HTML and Bootstrap snippets so that I can use them in every view.
<!doctype html>
<html lang="en">
<head>
<title> Laravel 7 CRUD - @yield('title')</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<div class="container mt-5">
@yield('content')
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
For inserting the post, we will create a form with inputs. So in the create-post.blade.php file, I have created the form with the form input box as showing below.
@extends('./master-layout')
@section('title')Create New Post @endsection
@section('content')
<div class="row">
<div class="col-xl-6 col-lg-6 col-12 m-auto">
<a href="{{route('post.index')}}" class="btn btn-danger btn-sm float-right"> Back to Posts </a>
</div>
</div>
<form action="{{route('post.store')}}" method="post">
@csrf
<div class="row mt-2">
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-12 m-auto">
<div class="card shadow">
@if(Session::has('success'))
<div class="alert alert-success alert-dismissible">
<button type="button" class="close" data-dismiss="alert">×</button>
{{Session::get("success")}}
</div>
@elseif(Session::has('failed'))
<div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert">×</button>
{{Session::get("failed")}}
</div>
@endif
<div class="card-header">
<h5 class="card-title"> Laravel 7 CRUD Application</h5>
</div>
<div class="card-body">
<div class="form-group">
<label for="title"> Post Title <span class="text-danger">*</span> </label>
<input type="text" name="title" id="title" class="form-control" placeholder="Enter Title" value="{{old('title')}}" />
{!!$errors->first('title', '<small class="text-danger"> :message </small>') !!}
</div>
<div class="form-group">
<label for="category"> Category <span class="text-danger">*</span> </label>
<input type="text" name="category" id="category" class="form-control" placeholder="Enter Category" value="{{old('category')}}" />
{!!$errors->first('category', '<small class="text-danger"> :message </small>') !!}
</div>
<div class="form-group">
<label for="title"> Description <span class="text-danger">*</span> </label>
<textarea class="form-control" name="description" placeholder="Enter Description">{{old('description')}}</textarea>
{!!$errors->first('description', '<small class="text-danger"> :message </small>') !!}
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-success">Publish Post</button>
</div>
</div>
</div>
</div>
</form>
@endsection
To show the post detail, we will have to create a post detail view. So, here I have used the same form layout as the create-post.blade.php file. The only difference is of the readonly attributes.
@extends('./master-layout')
@section('title')Show Post @endsection
@section('content')
<div class="row">
<div class="col-xl-6 col-lg-6 col-12 m-auto">
<a href="{{route('post.index')}}" class="btn btn-danger btn-sm float-right"> Back to Posts </a>
</div>
</div>
<div class="row mt-2">
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-12 m-auto">
<div class="card shadow">
<div class="card-header">
<h5 class="card-title"> Laravel 7 CRUD Application</h5>
</div>
<div class="card-body">
<div class="form-group">
<label for="title"> Post Title <span class="text-danger">*</span> </label>
<input type="text" name="title" id="title" class="form-control" placeholder="Enter Title" readonly value="@if(!empty($post)){{$post->title}}@else {{old('title')}} @endif" />
</div>
<div class="form-group">
<label for="category"> Category <span class="text-danger">*</span> </label>
<input type="text" name="category" id="category" class="form-control" placeholder="Enter Category" readonly value="@if(!empty($post)){{$post->category}}@else{{old('category')}} @endif" />
</div>
<div class="form-group">
<label for="title"> Description <span class="text-danger">*</span> </label>
<textarea class="form-control" name="description" readonly placeholder="Enter Description">@if(!empty($post)){{$post->description}}@else{{old('description')}}@endif</textarea>
</div>
</div>
</div>
</div>
</div>
@endsection
For editing the post, we will need to pass the data in the edit-post.blade.php. In this file, the data will be showing on the basis of post id. After clicking on the update button the post will be updated.
@extends('./master-layout')
@section('title')Update Post @endsection
@section('content')
<div class="row">
<div class="col-xl-6 col-lg-6 col-12 m-auto">
<a href="{{route('post.index')}}" class="btn btn-danger btn-sm float-right"> Back to Posts </a>
</div>
</div>
<form action="{{route('post.update',$post->id)}}" method="post">
@method("PUT")
@csrf
<div class="row mt-2">
<div class="col-xl-6 col-lg-6 col-md-12 col-sm-12 col-12 m-auto">
<div class="card shadow">
@if(Session::has('success'))
<div class="alert alert-success alert-dismissible">
<button type="button" class="close" data-dismiss="alert">×</button>
{{Session::get("success")}}
</div>
@elseif(Session::has('failed'))
<div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert">×</button>
{{Session::get("failed")}}
</div>
@endif
<div class="card-header">
<h5 class="card-title"> Laravel 7 CRUD Application | Update Post</h5>
</div>
<div class="card-body">
<div class="form-group">
<label for="title"> Post Title <span class="text-danger">*</span> </label>
<input type="text" name="title" id="title" class="form-control" placeholder="Enter Title" value="@if(!empty($post)){{$post->title}}@else {{old('title')}} @endif" />
{!!$errors->first('title', '<small class="text-danger"> :message </small>') !!}
</div>
<div class="form-group">
<label for="category"> Category <span class="text-danger">*</span> </label>
<input type="text" name="category" id="category" class="form-control" placeholder="Enter Category" value="@if(!empty($post)){{$post->category}}@else{{old('category')}} @endif" />
{!!$errors->first('category', '<small class="text-danger"> :message </small>') !!}
</div>
<div class="form-group">
<label for="title"> Description <span class="text-danger">*</span> </label>
<textarea class="form-control" name="description" placeholder="Enter Description">@if(!empty($post)){{$post->description}}@else{{old('description')}}@endif</textarea>
{!!$errors->first('description', '<small class="text-danger"> :message </small>') !!}
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-success">Update</button>
</div>
</div>
</div>
</div>
</form>
@endsection
In the index.php file, the posts will be listing. All the published post will be showing in this file. There are options to View, Edit and Delete the post.
@extends('./master-layout')
@section('title')Posts Listing | CRUD Application Laravel 7 @endsection
@section('content')
<div class="row mb-2">
<div class="col-xl-12 col-lg-12 col-12 m-auto">
<a href="{{route('post.create')}}" class="btn btn-primary btn-sm float-right"> Add New Post</a>
</div>
</div>
<table class="table table-striped">
<thead>
<tr>
<th> ID </th>
<th> Title </th>
<th> Category </th>
<th> Description </th>
<th> Created on </th>
<th> Status </th>
<th> Action </th>
</tr>
</thead>
<tbody>
@if(!@empty($posts))
@foreach($posts as $post)
<tr>
<td> {{$post->id}} </td>
<td> {{$post->title}} </td>
<td> {{$post->category}} </td>
<td> {{$post->description}} </td>
<td> {{$post->created_at}} </td>
<td> @if($post->published == 1) <span class="badge badge-success">Published</span> @else NA @endif </td>
<td>
<form action="{{route('post.destroy', $post->id)}}" method="post">
<a href="{{route('post.show', $post->id)}}" class="btn btn-info btn-sm"> View </a>
<a href="{{route('post.edit', $post->id)}}" class="btn btn-success btn-sm"> Edit </a>
@csrf
@method("DELETE")
<button type="submit" class="btn btn-danger btn-sm">Delete</button>
</form>
</td>
</tr>
@endforeach
@endif
</tbody>
</table>
@endsection
Create Routes
In Laravel 7, to call any controller function, we will need to define the route. Here, we have created a web application. Hence, we will need to define the route inside the web.php file.
The PostController contains the Resource method that’s why we will be using the resource route.
Route::resource('/laravel/post', 'PostController');
After creating the routes just run the application.
Run the Laravel 7 Application
To run the application simply use the artisan command.
php artisan serve
Fill the required details in the above form. Now click on the Publish Post button.
Here, I have created some posts. The post-listing will be looking like this.
In the post listing page, we have the option to View, Edit and Delete the post. So, when we click on the View, it will redirect to the Detail page as showing below.
For updating the post, simply click on the Edit option and make some change.
Now, click on the Update button, it will update the post.
Conclusion
Laravel 7 CRUD tutorial consists of the basic functionality of the database operation. You can create a new post, view the detail of the post, update the post with new changes and also, you can delete the post. For these all functionality, Laravel 7 provides the resource methods which are predefined. You don’t need to specify any function. This will allow you to work with a single route in which you can call all the functions easily.
Leave a Reply