Apps Artificial Intelligence CSS DevOps Go JavaScript Laravel Linux MongoDB MySQL PHP Python Rust Svelte Vue

Building a Simple CRUD Application in Laravel: A Practical Guide

2 min read .
Building a Simple CRUD Application in Laravel: A Practical Guide

Building a CRUD application is one of the best ways to learn the core pieces of Laravel. In this guide, we will create a simple Post resource that supports Create, Read, Update, and Delete operations using Eloquent, resource routes, validation, and Blade views.

1. Create the Laravel Project

Make sure Composer and a supported PHP version are installed, then run:

composer create-project --prefer-dist laravel/laravel laravel-crud
cd laravel-crud
php artisan serve

The development server is normally available at http://localhost:8000.

2. Configure the Database

Update .env for your database environment. For MySQL, for example:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_database
DB_USERNAME=your_database_user
DB_PASSWORD=your_database_password

Use a dedicated database account with only the privileges the application requires.

3. Create the Model and Migration

Generate a Post model and migration:

php artisan make:model Post -m

Edit the generated migration:

public function up(): void
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->text('content');
        $table->timestamps();
    });
}

Run the migration:

php artisan migrate

4. Create the CRUD Controller

Generate the controller:

php artisan make:controller PostController

Add the resource actions in app/Http/Controllers/PostController.php:

use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    public function index()
    {
        $posts = Post::latest()->get();

        return view('posts.index', compact('posts'));
    }

    public function create()
    {
        return view('posts.create');
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'title' => ['required', 'string', 'max:255'],
            'content' => ['required', 'string'],
        ]);

        Post::create($validated);

        return redirect()->route('posts.index');
    }

    public function show(Post $post)
    {
        return view('posts.show', compact('post'));
    }

    public function edit(Post $post)
    {
        return view('posts.edit', compact('post'));
    }

    public function update(Request $request, Post $post)
    {
        $validated = $request->validate([
            'title' => ['required', 'string', 'max:255'],
            'content' => ['required', 'string'],
        ]);

        $post->update($validated);

        return redirect()->route('posts.index');
    }

    public function destroy(Post $post)
    {
        $post->delete();

        return redirect()->route('posts.index');
    }
}

Using the validated array instead of $request->all() prevents unrelated request fields from being passed to Eloquent.

5. Configure the Post Model

Allow the intended fields to be mass assigned in app/Models/Post.php:

class Post extends Model
{
    use HasFactory;

    protected $fillable = ['title', 'content'];
}

6. Create Blade Views

Create a simple layout at resources/views/layouts/app.blade.php:

<html>
<head>
    <title>CRUD App - @yield('title')</title>
</head>
<body>
    <div class="container">
        @yield('content')
    </div>
</body>
</html>

An example resources/views/posts/index.blade.php:

@extends('layouts.app')

@section('content')
<h1>Posts</h1>
<a href="{{ route('posts.create') }}">Create New Post</a>

<ul>
@foreach($posts as $post)
    <li>
        <a href="{{ route('posts.show', $post) }}">{{ $post->title }}</a>
        <a href="{{ route('posts.edit', $post) }}">Edit</a>

        <form action="{{ route('posts.destroy', $post) }}" method="POST" style="display:inline;">
            @csrf
            @method('DELETE')
            <button type="submit">Delete</button>
        </form>
    </li>
@endforeach
</ul>
@endsection

Create similar create, edit, and show views with the appropriate form fields and actions. Keep @csrf on state-changing forms and use @method('PUT') or @method('PATCH') for updates.

7. Define Resource Routes

Add the resource route in routes/web.php:

use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Route;

Route::resource('posts', PostController::class);

Laravel generates the standard index, create, store, show, edit, update, and destroy routes.

8. Test the Application

Open http://localhost:8000/posts and test creating, viewing, editing, and deleting posts. Also test validation failures and missing records so you understand how Laravel handles unsuccessful requests.

Conclusion

A small CRUD application introduces several Laravel fundamentals at once: migrations, Eloquent models, validation, route-model binding, resource controllers, Blade templates, and CSRF protection. From here, you can add pagination, authorization policies, form requests, relationships, tests, or a richer frontend as the application grows.

Related Posts

chevron-up