Build a complete Laravel CRUD application with MySQL
In this tutorial, we will create a complete laravel CRUD application with features like error handling, pagination, and all the best practices so that you can improve the quality of your Laravel project.
For illustration consider the following application:
Contents
- Requirements
- Setup Laravel project
- Create Controller and Model
- Setup the Layout
- READ Operation
- CREATE Operation
- UPDATE Operation
- DELETE Operaton
- Conclusion
Requirements
- We are assuming that you have all the tools to run Laravel.
- Basic knowledge of Laravel and PHP.
Setup Laravel project
Firstly, we need to install Laravel. You can do it using the Composer create-project
command.
composer create-project --prefer-dist laravel/laravel laravel_crud
Secondly, create a database named laravel_crud
and configure it.
Open the .env file in your root path and setup the username and password.
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_crud
DB_USERNAME=root
DB_PASSWORD=
In addition we’ll create a table named articles
. You can so it creating a migration:
php artisan make:migration create_articles_table --create=articles
Check the file created in database/migrations/
and make this edition:
public function up()
{
Schema::create('articles', function (Blueprint $table) {
$table->increments('id');
$table->string('topic');
$table->text('description');
$table->string('categorie');
$table->timestamps();
});
}
Migrate it!
php artisan migrate
Sometimes it can give an error about maxLength, collection, or the charset. Therefore, if it is your case open AppServiceProvider.php in app/Providers/
and make this file looks like this:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Schema::defaultStringLength(191);
}
}
Create the views.
Setup a Resource Router. Open routes/web.php and add this line:
Route::resource('articles', 'ArticleController');
Create Controller and Model
We need to create a new controller as ArcticleController as well as its Model.
php artisan make:controller ArticleController
--resource --model=Article
Enter yes
to the question that will appear.
A App\Article model does not exist. Do you want to generate it? (yes/no) [yes]:
> yes
Open your model Article.php and create these variables:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
protected $fillable = [
'topic','description', 'categorie',
];
}
Open ArticleController.php:
Laravel left everything ready for us. You can see that you have some methods in your controller and now we’ll see how to manage them.
index() lists table data and make a pagination with three elements on each page.
public function index()
{
$articles = DB::table('articles')->paginate(3);
return view('articles.index', ['articles' => $articles]);
}
create() – Returns the View to create a table item.
public function create()
{
return view('articles.create');
}
store() – Saves the new item to the table
public function store(Request $request)
{
$request->validate([
'topic' => 'required',
'description' => 'required',
'categorie' => 'required',
]);
Article::create($request->all());
return redirect()->route('articles.index')
->with('success','Article created successfully.');
}
show() – Shows a specific item.
public function show(Article $article)
{
return view('articles.show',compact('article'));
}
edit() – Returns the View for editing the data
public function edit(Article $article)
{
return view('articles.edit',compact('article'));
}
update() – Save data update.
public function update(Request $request, Article $article)
{
$request->validate([
'topic' => 'required',
'description' => 'required',
'categorie' => 'required',
]);
$article->update($request->all());
return redirect()->route('articles.index')
->with('success','Article updated successfully');
}
delete() – Removes data.
public function destroy(Article $article)
{
$article->delete();
return redirect()->route('articles.index')
->with('success','Article deleted successfully');
}
Run it:
php artisan serve
And go to:
http://127.0.0.1:8000/articles
Setup the Layout
Open layout.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Layout</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
</head>
<body>
<div class="container">
<!-- Content here -->
@yield('content')
</div>
</body>
</html>
READ Operation
Open index.blade.php
@extends('articles.layout')
@section('content')
...
...
@endsection
Inside the section content add:
- Button to add a new article
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-right">
<a class="btn btn-primary" href="{{ route('articles.create') }}"> Create new article</a>
</div>
</div>
</div>
- Section to display a success message
@if ($message = Session::get('success'))
<div class="alert alert-success">
<p>{{ $message }}</p>
</div>
@endif
- And a table to display the articles:
<table class="table table-striped table-bordered">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Topic</th>
<th scope="col">Description</th>
<th scope="col">Categorie</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
@foreach ($articles as $article)
<tr>
<th scope="row">{{ $article->id }}</th>
<td>{{ $article->topic }}</td>
<td>{{ $article->description }}</td>
<td>{{ $article->categorie }}</td>
<td>
<form action="{{ route('articles.destroy',$article->id) }}" method="POST">
<a class="btn btn-info" href="{{ route('articles.show',$article->id) }}">Show</a>
<a class="btn btn-primary" href="{{ route('articles.edit',$article->id) }}">Edit</a>
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
- Finally, the links for the pagination:
{{ $articles->links() }}
CREATE Operation
Bellow, we have a button to return to the home/initial page, a section to display an error message and the form.
@extends('articles.layout')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2>Create Ne w Article</h2>
</div>
<div class="pull-right">
<a class="btn btn-info" href="{{ route('articles.index') }}"> Back</a>
</div>
</div>
</div>
@if ($errors->any())
<div class="alert alert-danger">
<strong>Warning!</strong> Please check your fields<br><br>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form action="{{ route('articles.store') }}" method="POST">
@csrf
<div class="form-group">
<label for="topic">Topic title</label>
<input type="text" class="form-control" placeholder="Enter Topic" name ="topic">
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea class="form-control" rows="3"placeholer ="Enter description" name="description"></textarea>
</div>
<div class="form-group">
<label for="categorie">Categorie</label>
<input type="text" class="form-control" placeholder="Enter Categorie" name ="categorie">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
@endsection
UPDATE Operation
A form to update the article:
@extends('articles.layout')
@section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2>Edit Article</h2>
</div>
<div class="pull-right">
<a class="btn btn-info" href="{{ route('articles.index') }}"> Back</a>
</div>
</div>
</div>
@if ($errors->any())
<div class="alert alert-danger">
<strong>Warning!</strong> Please check your fields.<br><br>
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form action="{{ route('articles.update',$article->id) }}" method="POST">
@csrf
@method('PUT')
<div class="form-group">
<label for="topic">Topic title</label>
<input type="text" class="form-control" value="{{ $article->topic }}" placeholder="Enter Topic" name ="topic">
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea class="form-control" rows="3" name="description">{{ $article->description }}</textarea>
</div>
<div class="form-group">
<label for="categorie">Categorie</label>
<input type="text" class="form-control" value="{{ $article->categorie }}" placeholder="Enter Categorie" name ="categorie">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
@endsection
DELETE Operaton
On index.blade.php you saw that we have these lines:
@method('DELETE')
<button type="submit" class="btn btn-danger">Delete</button>
Conclusion
As you can see Laravel gets everything ready for us. You can read about how to build a CRUD application using Laravel and VuejS.
You can find the source code here .
Keep Learning. Thanks for reading!