Laravel is a popular PHP framework for building modern and dynamic web applications in today’s fast-paced and ever-evolving web development landscape. One of its core features is Laravel Eloquent, an object-relational mapper (ORM) that enables developers to efficiently perform create, read, update, and delete (CRUD) operations on a database.
This tutorial demonstrates how to perform these operations in your Laravel application using Laravel’s Eloquent ORM and how to deploy your Laravel CRUD application using MyKinsta.
CRUD Functionality in Laravel
CRUD operations are the backbone of any database-driven application. They allow you to perform the most basic and essential database operations, such as creating new records, reading existing ones, and updating and deleting them. These operations are crucial to the functionality of any Laravel application that interacts with a database.
Eloquent provides a simple and intuitive way to interact with the database by decreasing the complexities of database management so that you can focus on building your application. Its built-in methods and classes enable you to easily CRUD records in the database.
Prerequisites
To follow this tutorial, ensure you have the following:
Steps
- Install Laravel and create a new application
- Create a database
- Create a table
- Create a controller
- Set up the model
- Add a route
- Generate Blade files
- Deploy and test your CRUD application
For guidance along the way, check out the tutorial’s complete code.
Install Laravel and Create a New Application
Open your terminal where you want to create your Laravel application and follow the steps below.
- To install Laravel, run:
composer global require laravel/installer
- To create a new Laravel application, run:
laravel new crudposts
Create a Database
To create a new database for your application:
- Start the Apache and MySQL servers in the XAMPP control panel and visit
http://localhost/phpmyadmin
in your browser.
- Click New on the left sidebar. You should see the following:
- Add a database name and click Create.
- Edit your application’s .env file at the root of your Laravel application. It contains all the environment variables used by the application. Locate the variables prefixed with
DB_
and edit them with your database credentials:
DB_CONNECTION=
DB_HOST=
DB_PORT=
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=
Create a Table
The rows of data in your application are stored in tables. You need just one table for this application, created using Laravel migrations.
- To create a table and generate a migration file using Laravel’s command-line interface, Artisan, run:
php artisan make:migration create_posts_table
The command above creates a new file,
yyyy_mm_dd_hhmmss_create_posts_table.php, in database/migrations.
- Open yyyy_mm_dd_hhmmss_create_posts_table.php to define the columns you want inside your database table in the up function:
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('body');
$table->timestamps();
});
}
This code defines what the posts table contains. It has four columns: id
, title
, body
, and timestamps
.
- Run the migrations files in the database/migrations folder to create tables in the database:
php artisan migrate
The output looks like this:
- Go to the database you created earlier to confirm you’ve created the tables:
Create a Controller
The controller contains all functions to CRUD posts from the database.
Generate a controller file inside your Laravel application using Artisan:
php artisan make:controller PostController --api
Running this command creates a PostController.php file in app/Http/Controllers, with boilerplate code and empty function declarations index
, store
, show
, update
, and destroy
.
Create Functions
Next, create the functions that store, index, update, destroy, create, show, and edit the data.
You can add them to the file app/Http/Controller/PostController.php shown below.
The store
Function
The store
function adds a post to the database.
Scroll to the store
function and add the following code inside the empty curly braces:
$request->validate([
'title' => 'required|max:255',
'body' => 'required',
]);
Post::create($request->all());
return redirect()->route('posts.index')
->with('success','Post created successfully.');
This code takes an object containing the post’s title and body, validates the data, adds a new post to the database if the data is valid, and redirects the user to the homepage with a success message.
The index
Function
The index
function fetches all the posts from the database and sends the data to the posts.index page.
The update
Function
The <update
function contains the id
of the post to update, the new post title
, and the body
. After validating the data, it finds the post with the same id
. If found, the update
function updates the post in the database with the new title
and body
. Then, it redirects the user to the homepage with a success message.
The destroy
Function
The destroy
function finds a post with the given id
and deletes it from the database, then redirects the user to the homepage with a success message.
The functions above are the functions used to CRUD posts from the database. However, you must define more functions inside the controller to render the necessary pages in resources/views/posts/.
The create
Function
The create
function renders the resources/views/posts/create.blade.php page, which contains the form for adding posts to the database.
The show
Function
The show
function finds a post with the given id
in the database and renders the resources/views/posts/show.blade.php file with the post.
The edit
Function
The edit
function finds a post with the given id
in the database and renders the resources/views/posts/edit.blade.php file with the post details inside a form.
Set Up the Model
The Post
model interacts with the posts table in the database.
- To create a model with Artisan, run:
php artisan make:model Post
This code creates a Post.php file inside the App/Models folder.
- Create a
<fillable
array. Add the following code inside thePost
class and below theuse HasFactory;
line
protected $fillable = [
'title',
'body',
];
This code creates a fillable
array that allows you to add items to the database from your Laravel application.
- Connect the
Post
model to the PostController.php file. Open PostController.php and add the line below underuse Illuminate\Http\Request;
. It looks like:
use Illuminate\Http\Request;
use App\Models\Post;
The PostController.php file should now look like this:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Post;
class PostController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$posts = Post::all();
return view('posts.index', compact('posts'));
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$request->validate([
'title' => 'required|max:255',
'body' => 'required',
]);
Post::create($request->all());
return redirect()->route('posts.index')
->with('success', 'Post created successfully.');
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$request->validate([
'title' => 'required|max:255',
'body' => 'required',
]);
$post = Post::find($id);
$post->update($request->all());
return redirect()->route('posts.index')
->with('success', 'Post updated successfully.');
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$post = Post::find($id);
$post->delete();
return redirect()->route('posts.index')
->with('success', 'Post deleted successfully');
}
// routes functions
/**
* Show the form for creating a new post.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
return view('posts.create');
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$post = Post::find($id);
return view('posts.show', compact('post'));
}
/**
* Show the form for editing the specified post.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
$post = Post::find($id);
return view('posts.edit', compact('post'));
}
}
Add Routes
After creating the controller functions and the Post
model, you must add routes for your controller functions.
- Open routes/web.php and delete the boilerplate route that the application generated. Replace it with the code below to connect the controller functions to their respective routes:
// returns the home page with all posts
Route::get('/', PostController::class .'@index')->name('posts.index');
// returns the form for adding a post
Route::get('/posts/create', PostController::class . '@create')->name('posts.create');
// adds a post to the database
Route::post('/posts', PostController::class .'@store')->name('posts.store');
// returns a page that shows a full post
Route::get('/posts/{post}', PostController::class .'@show')->name('posts.show');
// returns the form for editing a post
Route::get('/posts/{post}/edit', PostController::class .'@edit')->name('posts.edit');
// updates a post
Route::put('/posts/{post}', PostController::class .'@update')->name('posts.update');
// deletes a post
Route::delete('/posts/{post}', PostController::class .'@destroy')->name('posts.destroy');
- To connect the routes, open app/Http/Controllers/PostController.php and add the line below under the line
use Illuminate\Support\Facades\Route;
:
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;
The routes/web.php file should now look like this:
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;
// returns the home page with all posts
Route::get('/', PostController::class .'@index')->name('posts.index');
// returns the form for adding a post
Route::get('/posts/create', PostController::class . '@create')->name('posts.create');
// adds a post to the database
Route::post('/posts', PostController::class .'@store')->name('posts.store');
// returns a page that shows a full post
Route::get('/posts/{post}', PostController::class .'@show')->name('posts.show');
// returns the form for editing a post
Route::get('/posts/{post}/edit', PostController::class .'@edit')->name('posts.edit');
// updates a post
Route::put('/posts/{post}', PostController::class .'@update')->name('posts.update');
// deletes a post
Route::delete('/posts/{post}', PostController::class .'@destroy')->name('posts.destroy');
Generate Blade Files
Now that you have the routes, you can create the Laravel Blade files. Before using Artisan to generate the Blade files, create the make:view
command, with which you can generate blade.php files.
- Run the following code in the CLI to create a MakeViewCommand command file inside the app/Console/Commands folder:
php artisan make:command MakeViewCommand
- Create a command for generating .blade.php files from the CLI by replacing the code in the MakeViewCommand file with the following:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use File;
class MakeViewCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature="make:view {view}";
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new blade template.';
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$view = $this->argument('view');
$path = $this->viewPath($view);
$this->createDir($path);
if (File::exists($path))
{
$this->error("File {$path} already exists!");
return;
}
File::put($path, $path);
$this->info("File {$path} created.");
}
/**
* Get the view full path.
*
* @param string $view
*
* @return string
*/
public function viewPath($view)
{
$view = str_replace('.', '/', $view) . '.blade.php';
$path = "resources/views/{$view}";
return $path;
}
/**
* Create a view directory if it does not exist.
*
* @param $path
*/
public function createDir($path)
{
$dir = dirname($path);
if (!file_exists($dir))
{
mkdir($dir, 0777, true);
}
}
}
Create a Homepage
Next, create your homepage. The homepage is the index.blade.php file, which lists all the posts.
- To create the homepage, run:
php artisan make:view posts.index
This creates a posts folder inside the /resources/views folder and an index.blade.php file underneath it. The resulting path is /resources/views/posts/index.blade.php.
- Add the following code inside the index.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">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
<title>Posts</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-warning">
<div class="container-fluid">
<a class="navbar-brand h1" href={{ route('posts.index') }}>CRUDPosts</a>
<div class="justify-end ">
<div class="col ">
<a class="btn btn-sm btn-success" href={{ route('posts.create') }}>Add Post</a>
</div>
</div>
</div>
</nav>
<div class="container mt-5">
<div class="row">
@foreach ($posts as $post)
<div class="col-sm">
<div class="card">
<div class="card-header">
<h5 class="card-title">{{ $post->title }}</h5>
</div>
<div class="card-body">
<p class="card-text">{{ $post->body }}</p>
</div>
<div class="card-footer">
<div class="row">
<div class="col-sm">
<a href="https://kinsta.com/blog/laravel-crud/{{ route("posts.edit', $post->id) }}"
class="btn btn-primary btn-sm">Edit</a>
</div>
<div class="col-sm">
<form action="https://kinsta.com/blog/laravel-crud/{{ route("posts.destroy', $post->id) }}" method="post">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger btn-sm">Delete</button>
</form>
</div>
</div>
</div>
</div>
</div>
@endforeach
</div>
</div>
</body>
</html>
The code above creates a simple HTML page that uses Bootstrap for styling. It establishes a navigation bar and a grid template that lists all the posts in the database with details and two action buttons — edit and delete — using the @foreach
Blade helper.
The Edit button takes a user to the Edit post page, where they can edit the post. The Delete button deletes the post from the database using {{ route('posts.destroy', $post->id) }}
with a DELETE
method.
Note: The navbar code for all the files is the same as the previous file.
- Create the create.blade.php page. The Blade file called create adds posts to the database. Use the following command to generate the file:
php artisan make:view posts.create
This generates a create.blade.php file inside the /resources/views/posts folder.
- Add the following code to the create.blade.php file:
// same as the previous file. Add the following after the nav tag and before the closing body tag.
<div class="container h-100 mt-5">
<div class="row h-100 justify-content-center align-items-center">
<div class="col-10 col-md-8 col-lg-6">
<h3>Add a Post</h3>
<form action="https://kinsta.com/blog/laravel-crud/{{ route("posts.store') }}" method="post">
@csrf
<div class="form-group">
<label for="title">Title</label>
<input type="text" class="form-control" id="title" name="title" required>
</div>
<div class="form-group">
<label for="body">Body</label>
<textarea class="form-control" id="body" name="body" rows="3" required></textarea>
</div>
<br>
<button type="submit" class="btn btn-primary">Create Post</button>
</form>
</div>
</div>
</div>
The code above creates a form with title
and body
fields and a submit
button for adding a post to the database through the {{ route('posts.store') }}
action with a POST
method.
- Create the Edit post page to edit posts in the database. Use the following command to generate the file:
php artisan make:view posts.edit
This creates an edit.blade.php file inside the /resources/views/posts folder.
- Add the following code to the edit.blade.php file:
<div class="container h-100 mt-5">
<div class="row h-100 justify-content-center align-items-center">
<div class="col-10 col-md-8 col-lg-6">
<h3>Update Post</h3>
<form action="https://kinsta.com/blog/laravel-crud/{{ route("posts.update', $post->id) }}" method="post">
@csrf
@method('PUT')
<div class="form-group">
<label for="title">Title</label>
<input type="text" class="form-control" id="title" name="title"
value="{{ $post->title }}" required>
</div>
<div class="form-group">
<label for="body">Body</label>
<textarea class="form-control" id="body" name="body" rows="3" required>{{ $post->body }}</textarea>
</div>
<button type="submit" class="btn mt-3 btn-primary">Update Post</button>
</form>
</div>
</div>
</div>
The code above creates a form with title
and body
fields and a submit button for editing a post with the specified id
in the database through the {{ route('posts.update') }}
action with a PUT
method.
- Then, restart your application server using the code below:
php artisan serve
Visit http://127.0.0.1:8000
on your browser to view your new blog. Click the Add Post button to add new posts.
Deploy and Test Your CRUD Application
Prepare your application for deployment as follows.
- Make the deployment smooth and straightforward by declaring the public folder. Add a .htaccess file to the root of the application folder with the following code:
<IfModule mod_rewrite.c >
RewriteEngine On
RewriteRule ^(.*)$ public/$1 [L]
</IfModule >
- Force your app to use
HTTPS
by adding the following code above your routes inside the routes/web.php file:
use Illuminate\Support\Facades\URL;
URL::forceScheme('https');
- Push your code to a Git repository. Kinsta supports deployments from GitHub, GitLab, or Bitbucket.
Set Up a Project on MyKinsta
- Create a MyKinsta account if you don’t have one already.
- Log in to your account and click the Add Service button on the Dashboard to create a new application.
- If you’re new to the app, connect to your GitHub, GitLab, or Bitbucket account and give specific permissions.
- Fill out the form, and add the
APP_KEY
. You can find its corresponding value in your .env file.
- Select your build resources and whether you want to use your application build path or build your application with Dockerfile. For this demonstration, let MyKinsta build the app based on your repository.
- Specify the different processes you want to run during deployment. You can leave it blank at this point.
- Lastly, add your payment method.
After confirming your payment method, MyKinsta deploys your application and assigns you a URL as shown below:
You can visit the link, but you get a 500 | Server Error
page because the app needs a valid database connection to work. The following section resolves this problem.
Create a Database via MyKinsta
- To create a database, go to your MyKinsta dashboard and click Add Service.
- Select Database and complete the form with your preferred database name, type, username, and password. Add a data center location and a database size that fits your application.
- The next page displays the cost summary and your payment method. Click Create Database to complete the process.
- After creating the database, MyKinsta redirects you to your services list. Click the database you just created and scroll down to External Connections. Copy the database credentials.
- Go back to the application’s Deployment page and click Settings. Then, scroll down to Environment Variables and click Add Environment Variables. Add the database credentials as environment variables in the following order:
DB_CONNECTION=mysql
DB_HOST=External hostname
DB_PORT=External port
DB_DATABASE=Database name
DB_USERNAME=Username
DB_PASSWORD=Password
The application environment variables list should now look like this:
- Go to your application’s Deployments page and manually deploy your application by clicking Deploy Now to apply these changes. So far, you’ve created a database and connected it to your application.
- Finally, to create the database tables in your MyKinsta database, connect the database to your local app by updating your .env file with the same credentials you entered in your app at MyKinsta and run the following command:
php artisan migrate
This command runs all the migration files. It creates all the defined tables in your MyKinsta application.
Now, you can test your application with the URL assigned after the first deployment.
Summary
Laravel is a comprehensive framework for creating robust and scalable web applications that require CRUD functionality. With its intuitive syntax and powerful features, Laravel makes it easy to build CRUD operations into your application.
This article covered the fundamental concepts of CRUD operations and how to implement them using Laravel’s built-in features. It also explained:
- How to create a database in MyKinsta and connect it to your application
- How to use Laravel’s migrations to define the database table, create the controller file and its functions
- Define a model and connect it to the controller. Laravel’s routing generates Blade files to create corresponding pages and forms and to deploy and test the application using MyKinsta
Now that you’ve seen how easy it is to perform CRUD operations in Laravel, check out MyKinsta for web application development and hosting.