How to Create a CRUD Application in Laravel

Learn how to build a complete CRUD (Create, Read, Update, Delete) application in Laravel step-by-step.
This guide covers model creation, migration setup, controller logic, route handling, and Blade views.
You’ll also learn how to connect to a database and use Laravel’s resource controller.
It’s ideal for beginners looking to understand Laravel’s MVC structure.
By the end, you’ll have a functional and clean Laravel CRUD system.

Step 1: Install Laravel Project

put this commect in your project terminal:


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

Step 2: Create a Database & Configure .env

In .env, update your DB settings:


DB_DATABASE=laravel_crud
DB_USERNAME=root
DB_PASSWORD=

Then create this database in MySQL: laravel_crud

Step 3: Create Model, Migration & Controller

Let’s create a Post model:

put this commect in your project terminal:


php artisan make:model Post -mcr

This creates:

  • Post.php model
  • create_posts_table migration
  • PostController

Step 4: Define Table Fields in Migration

Edit database/migrations/xxxx_create_posts_table.php:


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

Run the migration:

put this commect in your project terminal:


php artisan migrate

Step 5: Define Routes in web.php

Edit routes/web.php:


use App\Http\Controllers\PostController;

Route::get('/', function () {
    return redirect('/posts');
});

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

Step 6: Create Blade Views

Create a folder resources/views/posts/ and inside it, create:

📄 index.blade.php


@extends('layout')

@section('content')
<h2>All Posts</h2>
<a href="{{ route('posts.create') }}">Create New Post</a>
@foreach($posts as $post)
    <div style="border:1px solid #ccc; margin:10px; padding:10px;">
        <h3>{{ $post->title }}</h3>
        <p>{{ $post->content }}</p>
        <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>
    </div>
@endforeach
@endsection

📄 create.blade.php


@extends('layout')

@section('content')
<h2>Create Post</h2>
<form method="POST" action="{{ route('posts.store') }}">
    @csrf
    Title: <input type="text" name="title"><br><br>
    Content:<br>
    <textarea name="content"></textarea><br><br>
    <button type="submit">Save</button>
</form>
@endsection

📄 edit.blade.php


@extends('layout')

@section('content')
<h2>Edit Post</h2>
<form method="POST" action="{{ route('posts.update', $post) }}">
    @csrf
    @method('PUT')
    Title: <input type="text" name="title" value="{{ $post->title }}"><br><br>
    Content:<br>
    <textarea name="content">{{ $post->content }}</textarea><br><br>
    <button type="submit">Update</button>
</form>
@endsection

📄 layout.blade.php


<!DOCTYPE html>
<html>
<head>
    <title>Laravel CRUD</title>
</head>
<body>
    <h1>Laravel CRUD Example</h1>
    @yield('content')
</body>
</html>

Step 7: Controller Logic

Edit app/Http/Controllers/PostController.php:


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

class PostController extends Controller
{
    public function index() {
        $posts = Post::all();
        return view('posts.index', compact('posts'));
    }

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

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

        Post::create($request->all());
        return redirect()->route('posts.index');
    }

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

    public function update(Request $request, Post $post) {
        $post->update($request->all());
        return redirect()->route('posts.index');
    }

    public function destroy(Post $post) {
        $post->delete();
        return redirect()->route('posts.index');
    }
}

Step 8: Add Fillable Fields in Model

Edit app/Models/Post.php:


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

Done!

Now visit http://127.0.0.1:8000/posts to test full CRUD.