To create a CRUD application in Laravel, your machine should have PHP version >= 7.3 and a composer with additional extensions.
- BCMath PHP Extension
- Ctype PHP Extension
- OpenSSL PHP Extension
- PDO PHP Extension
- Tokenizer PHP Extension
- XML PHP Extension
- Fileinfo PHP Extension
- JSON PHP Extension
- Mbstring PHP Extension
Step 1: Installing Laravel
If you are using Laravel Valet, you need to update your system to create the latest laravel project. You can find more in the Laravel Valet upgrade guide.
You can also install Laravel using the following command.
composer create-project laravel/laravel --prefer-dist laravel8crud
I will use Visual Studio Code as an editor for this project.
Step 2: Configure the MySQL Database
We will use a MySQL database to create a Database and return it to the project.
Laravel provides the .env file to add credentials. Open the file and edit the following code.
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=laravel8crud DB_USERNAME=root DB_PASSWORD=root
Your username and password will differ based on your database credentials.
Laravel comes with default migrations like users, password_resets, and create_failed_jobs table. Now go to the terminal and type the following command to run your migrations.
php artisan migrate
You can see in your database that these tables are created, and those tables are empty.
Step 3: Create a model and custom migration
We will create a project around Playstation 5 games. So users can create PS5 games, edit, and delete the games. So, let’s create a Game model and migration.
php artisan make:model Game -m
It will create two files.
- Game.php model
- create_games_table migration
Add the new fields inside the create_games_table.php migration file.
// create_games_table.php public function up() { Schema::create('games', function (Blueprint $table) { $table->id(); $table->string('name'); $table->integer('price'); $table->timestamps(); }); }
The id and timestamp fields are created by Laravel by default. The name and price are custom fields that the user can add via the web forms.
Finally, you can run the migration to create the table in the database.
php artisan migrate
Step 4: Create a Laravel controller.
Laravel resource routing assigns the typical “CRUD” routes to a controller with a single line of code. Since our application is basic crud operations, we will use the Resource Controller for this small project.
php artisan make:controller GameController --resource
In a fresh install of Laravel, no namespace prefix is applied to the route groups that your routes are loaded into.
In previous releases of Laravel, the
RouteServiceProvider
contained a$namespace
property. This property’s value would automatically be prefixed onto controller route definitions and calls to theaction
helper /URL::action
method. In Laravel, this property isnull
by default. This means that no automatic namespace prefixing will be done by Laravel.” Laravel Docs – Release Notes.
You can open the App\Providers\RouteServiceProvider.php file and modify the following code inside the boot() method.
// RouterServiceProvider.php Route::middleware('web') ->namespace('App\Http\Controllers') ->group(base_path('routes/web.php'));
That is it. Now it can find the controller. You must assign the path in the namespace if your controller files are elsewhere.
Note here that I have added the –resource flag, which will define six methods inside the GameController, namely:
- Index: (The index() method displays a list of games).
- Create: (The create() method will show the Form or view for creating a game).
- Store: (The store() method is used for creating a game inside the database. Note: create method submits the form data to the store() method).
- Show: (The show() method will display a specified game).
- Edit: (The edit() method will show the Form for editing a game. Form will be filled with the existing game data).
- Update: (The update() method is used for updating a game inside the database. Note: edit() method submits the form data to the update() method).
- Destroy: (The destroy() method is used for deleting the specified game).
By default, the GameController.php file is created inside the app >> Http >> controllers folder.
<?php // GameController.php namespace App\Http\Controllers; use Illuminate\Http\Request; class GameController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // } /** * 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) { // } }
You can see that the file contains CRUD operations in the form of different functions. We will use these functions, one by one, to create crud operations.
The –resource flag will call the internal resource() method by Laravel to generate the following routes. You can check out the route list using the following command.
php artisan route: list
Step 5: Define routes
To define a route in Laravel, you must add the route code inside the routes >> web.php file.
// web.php Route::resource('games', 'GameController');
Step 6: Configure Bootstrap in Laravel
Laravel provides Bootstrap and Vue scaffolding 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
Please run “npm install && npm run dev” to compile your fresh scaffolding.
Step 7: Create Views in Laravel
Views contain the HTML served by your application and separate your controller/application logic from your presentation logic. Views are stored in the resources/views directory.
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.
<!-- layout.blade.php --> <!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 CRUD Tutorial</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-blade files.
- create.blade.php
- edit.blade.php
- index.blade.php
Inside the create.blade.php file, write the following code.
<!-- create.blade.php --> @extends('layout') @section('content') <style> .uper { margin-top: 40px; } </style> <div class="card uper"> <div class="card-header"> Add Games 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('games.store') }}"> <div class="form-group"> @csrf <label for="country_name">Game Name:</label> <input type="text" class="form-control" name="name"/> </div> <div class="form-group"> <label for="cases">Price :</label> <input type="text" class="form-control" name="price"/> </div> <button type="submit" class="btn btn-primary">Add Game</button> </form> </div> </div> @endsection
In this code, we have defined the action, which will call the store() method of the GameController’s method. Remember, we have used the resource controller.
Now, we need to return this create view from the create() method of GameController. So write the following code inside the GameController’s create() method.
// GameController.php public function create() { return view('create'); }
Go to https://laravel8crud.test/games/create or http://localhost:8000, and you will see something like the one below.
Step 8: Add Validation rules and store the data.
In this step, we will add a Laravel form Validation.
Add the GameController.php to import the namespace of the Game model inside the GameController.php file.
<?php // GameController.php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Game;
Write the following code inside the GameController.php file’s store() function.
// GameController.php public function store(Request $request) { $validatedData = $request->validate([ 'name' => 'required|max:255', 'price' => 'required', ]); $show = Game::create($validatedData); return redirect('/games')->with('success', 'Game is successfully saved'); }
We use the $request->validate() method for validation, which receives an array of validation rules. The
Validation rules[] is the associative array. The key will be the field_name and the validation rules value.
The second parameter is an optional array for custom validation messages. Rules are separated with a pipe sign “|”. In this example, we are using the most basic validation rules.
If the validation fails, it will redirect back to the form page with error messages. On the other hand, if the validation passes, it will create a new game and save it in the database.
In case of errors, we need to loop through those error messages inside the create.blade.php file, which we have already done.
If you leave all the form fields empty, you will find an error message like this image.
We can see that we got the errors, but if we fill in all the correct data, you will still not save the data into the database because of the Mass Assignment Exception.
To prevent the Mass Assignment Exception, we need to add a $fillable array inside the Game.php model.
<?php // Game.php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Game extends Model { use HasFactory; protected $fillable = ['name', 'price']; }
Now, filling in the correct form fields creates a new row in the database.
Step 9: Display the games
To display the list of games, we need to write the HTML code inside the index.blade.php file. But before that, let’s write the index() function of the GameController.php file to get the array of data from the database.
// GameController.php public function index() { $games = Game::all(); return view('index',compact('games')); }
Now, write the following code inside the index.blade.php file.
<!-- index.blade.php --> @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>Game Name</td> <td>Game Price</td> <td colspan="2">Action</td> </tr> </thead> <tbody> @foreach($games as $game) <tr> <td>{{$game->id}}</td> <td>{{$game->name}}</td> <td>{{$game->price}}</td> <td><a href="{{ route('games.edit', $game->id)}}" class="btn btn-primary">Edit</a></td> <td> <form action="{{ route('games.destroy', $game->id)}}" method="post"> @csrf @method('DELETE') <button class="btn btn-danger" type="submit">Delete</button> </form> </td> </tr> @endforeach </tbody> </table> <div> @endsection
We added two edit and delete buttons to perform the respective operations.
Step 10: Complete Edit and Update
To edit the data, we need the data from the database.
Add the following code inside the GameController.php file’s edit function.
// GameController.php public function edit($id) { $game = Game::findOrFail($id); return view('edit', compact('game')); }
Create the new file inside the views folder 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 Game 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('games.update', $game->id ) }}"> <div class="form-group"> @csrf @method('PATCH') <label for="country_name">Game Name:</label> <input type="text" class="form-control" name="name" value="{{ $game->name }}"/> </div> <div class="form-group"> <label for="cases">Game Price :</label> <input type="text" class="form-control" name="price" value="{{ $game->price }}"/> </div> <button type="submit" class="btn btn-primary">Update Data</button> </form> </div> </div> @endsection
Now go to the index and edit page of a specific game, and you will see the Form with filled values.
Add the following code inside the GameController’s update() function.
// GameController.php public function update(Request $request, $id) { $validatedData = $request->validate([ 'name' => 'required|max:255', 'price' => 'required' ]); Game::whereId($id)->update($validatedData); return redirect('/games')->with('success', 'Game Data is successfully updated'); }
Now you can update all the data in the database.
Step 11: Create Delete Functionality
We will use GameController’s destroy() function to remove data from the database.
// GameController.php public function destroy($id) { $game = Game::findOrFail($id); $game->delete(); return redirect('/games')->with('success', 'Game Data is successfully deleted'); }
The delete() function is provided by Laravel to remove the data from the Database.
The complete controller file is this.
<?php // GameController.php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Game; class GameController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { $games = Game::all(); return view('index',compact('games')); } /** * 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([ 'name' => 'required|max:255', 'price' => 'required', ]); $show = Game::create($validatedData); return redirect('/games')->with('success', 'Game 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) { $game = Game::findOrFail($id); return view('edit', compact('game')); } /** * 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([ 'name' => 'required|max:255', 'price' => 'required' ]); Game::whereId($id)->update($validatedData); return redirect('/games')->with('success', 'Game Data is successfully updated'); } /** * Remove the specified resource from storage. * * @param int $id * @return \Illuminate\Http\Response */ public function destroy($id) { $game = Game::findOrFail($id); $game->delete(); return redirect('/games')->with('success', 'Game Data is successfully deleted'); } }
That is it. Now, you can create, read, update, and delete the data in Laravel.
If you are interested in the FrontEnd Javascript framework like Vue with Laravel or Angular with Laravel, check out the guides like Vue Laravel CRUD and Angular Laravel example.
I have put the whole crud operation code on Github, so you can also check it out.

Krunal Lathiya is a seasoned Computer Science expert with over eight years in the tech industry. He boasts deep knowledge in Data Science and Machine Learning. Versed in Python, JavaScript, PHP, R, and Golang. Skilled in frameworks like Angular and React and platforms such as Node.js. His expertise spans both front-end and back-end development. His proficiency in the Python language stands as a testament to his versatility and commitment to the craft.
“So write the following code inside the GameController’s create() method.”
But I didn’t see the code. Can you post the complete code of GameController.php ?
Thank you very much!
-Tom
Thanks. I found it. The old way has “games.create”, but version 8 does not need “games.” at all.
Nice tutorial.
Thank you very much!
Tom
Missing a semicolon
public function create()
{
return view(‘create’)
}
Nice tutorial which is show how simple VS pure PHP Laravel is made.
Only this tutorial show me alot about Laravel.
Thanks
People called me timon.
Really Thank you for your help.
I studied very well with your guide.
Now , I can know about laravel a bit!
I recommended this url much!
many thanks man! yesterday i jst frustated abt new method in routing, im using Route::resources(”, function, SumSimSam::class, ‘index’) and it fail, it apparently all you need to edit is App\Providers\Routeserviceprovider and everythings works well now^ – thx a lot mate
Prime
Thank you
im’ sorry i copy all code and in browser i think don’t load bootstrap
why?
You can use https://github.com/wkasunsampath/laravel-autocrud to simplify this process.
With this library, you can create a fully working CRUD with just one artisan command.
For instance, to create a CRUD for Users model, you just have to type
php artisan autocrud:create User
All done! you have a working CRUD.