How to Build Your First Laravel CRUD Application: A Complete Beginner’s Guide (2025)

Learn to build your first Laravel CRUD application with this step-by-step tutorial. Create a blog management system using Laravel 11, Eloquent ORM, and Blade templates in 30 minutes
Laravel CRUD tutorial, Laravel beginner guide, Laravel blog application, PHP Laravel tutorial, Laravel MVC example, Laravel, PHP

Learn to create a simple blog management system with Laravel 11 in just 30 minutes. Perfect for beginners starting their Laravel journey.

Building your first Laravel application can seem overwhelming, but creating a simple CRUD (Create, Read, Update, Delete) system is the perfect way to understand Laravel’s core concepts. In this tutorial, we’ll build a basic blog post management system that will teach you the fundamentals of Laravel development.

What You’ll Learn

  • Setting up a fresh Laravel project
  • Creating models, migrations, and controllers
  • Building views with Blade templating
  • Implementing full CRUD functionality
  • Basic form validation
  • Routing in Laravel

Prerequisites

Before we start, make sure you have:

  • PHP 8.1+ installed on your system
  • Composer (PHP package manager)
  • A code editor (VS Code recommended)
  • Basic knowledge of PHP and HTML

Step 1: Setting Up Your Laravel Project

First, let’s create a new Laravel project using Composer:

composer create-project laravel/laravel blog-crud-app
cd blog-crud-app

Start the development server:

php artisan serve

Your Laravel application will be available at http://localhost:8000.

Step 2: Creating the Database and Migration

Laravel uses migrations to manage database schema. Let’s create a migration for our blog posts:

php artisan make:migration create_posts_table

Open the migration file in database/migrations/ and update it:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

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

public function down()
{
Schema::dropIfExists('posts');
}
};

Run the migration:

php artisan migrate

Step 3: Creating the Post Model

Generate a model for our blog posts:

php artisan make:model Post

Update the app/Models/Post.php file:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
use HasFactory;

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

Step 4: Creating the Controller

Laravel controllers handle the business logic. Create a resource controller:

php artisan make:controller PostController --resource

Update app/Http/Controllers/PostController.php:

<?php

namespace App\Http\Controllers;

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)
{
$request->validate([
'title' => 'required|max:255',
'content' => 'required',
'author' => 'required|max:255'
]);

Post::create($request->all());

return redirect()->route('posts.index')
->with('success', 'Post created successfully!');
}

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)
{
$request->validate([
'title' => 'required|max:255',
'content' => 'required',
'author' => 'required|max:255'
]);

$post->update($request->all());

return redirect()->route('posts.index')
->with('success', 'Post updated successfully!');
}

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

return redirect()->route('posts.index')
->with('success', 'Post deleted successfully!');
}
}

Step 5: Setting Up Routes

Add the resource routes to routes/web.php:

<?php

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

Route::get('/', function () {
return redirect()->route('posts.index');
});

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

Step 6: Creating the Views

Create the views directory and files:

mkdir resources/views/posts
Layout File (resources/views/layouts/app.blade.php)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@yield('title', 'Laravel CRUD App')</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand" href="{{ route('posts.index') }}">Blog CRUD</a>
</div>
</nav>

<div class="container mt-4">
@if(session('success'))
<div class="alert alert-success">
{{ session('success') }}
</div>
@endif

@yield('content')
</div>
</body>
</html>
Index View (resources/views/posts/index.blade.php)
@extends('layouts.app')

@section('title', 'All Posts - Laravel CRUD')

@section('content')
<div class="d-flex justify-content-between align-items-center mb-4">
<h1>All Blog Posts</h1>
<a href="{{ route('posts.create') }}" class="btn btn-primary">Create New Post</a>
</div>

@if($posts->count() > 0)
<div class="row">
@foreach($posts as $post)
<div class="col-md-6 mb-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">{{ $post->title }}</h5>
<p class="card-text">{{ Str::limit($post->content, 100) }}</p>
<p class="text-muted">By {{ $post->author }} • {{ $post->created_at->diffForHumans() }}</p>
<div class="btn-group" role="group">
<a href="{{ route('posts.show', $post) }}" class="btn btn-sm btn-outline-primary">View</a>
<a href="{{ route('posts.edit', $post) }}" class="btn btn-sm btn-outline-secondary">Edit</a>
<form action="{{ route('posts.destroy', $post) }}" method="POST" class="d-inline">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-sm btn-outline-danger"
onclick="return confirm('Are you sure?')">Delete</button>
</form>
</div>
</div>
</div>
</div>
@endforeach
</div>
@else
<div class="text-center py-5">
<h3>No posts found</h3>
<p>Get started by creating your first blog post!</p>
<a href="{{ route('posts.create') }}" class="btn btn-primary">Create New Post</a>
</div>
@endif
@endsection
Create View (resources/views/posts/create.blade.php)
@extends('layouts.app')

@section('title', 'Create New Post - Laravel CRUD')

@section('content')
<div class="row justify-content-center">
<div class="col-md-8">
<h1>Create New Blog Post</h1>

@if ($errors->any())
<div class="alert alert-danger">
<ul class="mb-0">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif

<form action="{{ route('posts.store') }}" method="POST">
@csrf
<div class="mb-3">
<label for="title" class="form-label">Title</label>
<input type="text" class="form-control" id="title" name="title" value="{{ old('title') }}" required>
</div>

<div class="mb-3">
<label for="author" class="form-label">Author</label>
<input type="text" class="form-control" id="author" name="author" value="{{ old('author') }}" required>
</div>

<div class="mb-3">
<label for="content" class="form-label">Content</label>
<textarea class="form-control" id="content" name="content" rows="10" required>{{ old('content') }}</textarea>
</div>

<div class="mb-3">
<button type="submit" class="btn btn-primary">Create Post</button>
<a href="{{ route('posts.index') }}" class="btn btn-secondary">Cancel</a>
</div>
</form>
</div>
</div>
@endsection

Step 7: Testing Your CRUD Application

  1. Start your Laravel development server: php artisan serve
  2. Visit http://localhost:8000
  3. Create a few blog posts using the “Create New Post” button
  4. Test editing and deleting posts
  5. Verify that validation works by submitting empty forms

Common Laravel CRUD Patterns You’ve Learned

Model-View-Controller (MVC) Architecture

  • Model: Handles database interactions (Post.php)
  • View: Manages presentation layer (Blade templates)
  • Controller: Contains business logic (PostController.php)

Eloquent ORM Features

  • Post::create() – Mass assignment for creating records
  • Post::latest() – Ordering records by creation date
  • Route model binding – Automatic model injection

Blade Templating

  • Template inheritance with @extends and @yield
  • Looping with @foreach
  • Conditional rendering with @if
  • Cross-site request forgery protection with @csrf

Next Steps to Enhance Your Laravel Skills

  1. Add Image Upload: Learn file handling in Laravel
  2. Implement User Authentication: Use Laravel Breeze or Jetstream
  3. Add Categories: Create relationships between models
  4. API Development: Convert your CRUD to a REST API
  5. Testing: Write feature tests for your application

SEO Tips for Your Laravel Blog

  • Use semantic HTML structure with proper heading hierarchy
  • Implement meta descriptions and title tags dynamically
  • Add Open Graph tags for social media sharing
  • Consider adding breadcrumb navigation
  • Optimize images with alt tags and proper sizing
Conclusion

Congratulations! You’ve successfully built your first Laravel CRUD application. This foundation gives you the essential knowledge to build more complex Laravel applications. The combination of Eloquent ORM, Blade templating, and Laravel’s routing system makes web development both powerful and enjoyable.

Key takeaways from this tutorial:

  • Laravel’s convention over configuration approach speeds up development
  • Resource controllers provide a clean structure for CRUD operations
  • Blade templating makes creating dynamic views straightforward
  • Laravel’s validation system helps maintain data integrity

Start experimenting with additional features like pagination, search functionality, or user authentication to continue your Laravel learning journey.

Previous Article

Google Pixel 10 becomes first phone to make WhatsApp calls via satellite

Next Article

Getting Started with Laravel Queues – A Beginner’s Guide

Write a Comment

Leave a Comment

Your email address will not be published. Required fields are marked *