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

  1. Install Laravel and create a new application
  2. Create a database
  3. Create a table
  4. Create a controller
  5. Set up the model
  6. Add a route
  7. Generate Blade files
  8. 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.

  1. To install Laravel, run:
composer global require laravel/installer
  1. To create a new Laravel application, run:
laravel new crudposts

Create a Database

To create a new database for your application:

  1. Start the Apache and MySQL servers in the XAMPP control panel and visit http://localhost/phpmyadmin in your browser.
  1. Click New on the left sidebar. You should see the following:
The create database form.
The create database form.
  1. Add a database name and click Create.
  1. 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.

  1. 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.

  1. 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.

  1. Run the migrations files in the database/migrations folder to create tables in the database:
php artisan migrate

The output looks like this:

Running migrations output
Running the migrations.
  1. Go to the database you created earlier to confirm you’ve created the tables:
Created tables.
Created 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.

  1. To create a model with Artisan, run:
php artisan make:model Post

This code creates a Post.php file inside the App/Models folder.

  1. Create a fillable array. Add the following code inside the Post class and below the use 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.

  1. Connect the Post model to the PostController.php file. Open PostController.php and add the line below under use 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.

  1. 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');
  1. 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.

  1. Run the following code in the CLI to create a MakeViewCommand command file inside the app/Console/Commands folder:
php artisan make:command MakeViewCommand
  1. 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.

  1. 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.

  1. 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="{{ route('posts.edit', $post->id) }}"
            class="btn btn-primary btn-sm">Edit</a>
                </div>
                <div class="col-sm">
                    <form action="{{ 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.

  1. 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.

  1. 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="{{ 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.

  1. 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.

  1. 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="{{ 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.

  1. 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.

  1. 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 >
  1. 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');
  1. Push your code to a Git repository. Kinsta supports deployments from GitHub, GitLab, or Bitbucket.

Set Up a Project on MyKinsta

  1. Create a MyKinsta account if you don’t have one already.
  1. Log in to your account and click the Add Service button on the Dashboard to create a new application.
  1. If you’re new to the app, connect to your GitHub, GitLab, or Bitbucket account and give specific permissions.
  1. Fill out the form, and add the APP_KEY. You can find its corresponding value in your .env file.
  1. 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.
  1. Specify the different processes you want to run during deployment. You can leave it blank at this point.
  1. Lastly, add your payment method.

After confirming your payment method, MyKinsta deploys your application and assigns you a URL as shown below:

Successful deployment using MyKinsta
Successful deployment.

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

  1. To create a database, go to your MyKinsta dashboard and click Add Service.
  1. 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.
  1. The next page displays the cost summary and your payment method. Click Create Database to complete the process.
  1. 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.
  1. 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:

The .env variables list.
The .env variables list.
  1. 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.
  1. 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.

Marcia Ramos Kinsta

I'm the Editorial Team Lead at Kinsta. I'm a open source enthusiast and I love coding. With more than 7 years of technical writing and editing for the tech industry, I love collaborating with people to create clear and concise pieces of content and improve workflows.