Copied!
Laravel

How to Set Up PostgreSQL with Laravel and Build a CRUD Application

laravel-and-pgsql-crud
Shahroz Javed
Jun 09, 2025 . 105 views

Table Of Contents

 

Introduction

PostgreSQL is a powerful open-source relational database. If you're looking to integrate it with Laravel for a scalable and production-ready stack, you're in the right place. This guide walks you through how to configure Laravel to use PostgreSQL and build a simple product CRUD module using Eloquent and Blade.

Step 1: Create Laravel Project

composer create-project laravel/laravel pgsql-crud

Step 2: Configure PostgreSQL Database

Update your .env file:

DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=pgsql_db
DB_USERNAME=postgres
DB_PASSWORD=password
  

Also update config/database.php if needed:

'pgsql' => [
    'driver' => 'pgsql',
    'host' => env('DB_HOST', '127.0.0.1'),
    'port' => env('DB_PORT', '5432'),
    'database' => env('DB_DATABASE', 'forge'),
    'username' => env('DB_USERNAME', 'forge'),
    'password' => env('DB_PASSWORD', ''),
    'charset' => 'utf8',
    'prefix' => '',
    'schema' => 'public',
],
  

Step 3: Create Product Model and Migration

php artisan make:model Product -m

Update the migration:

Schema::create('products', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->decimal('price', 10, 2);
    $table->text('description')->nullable();
    $table->timestamps();
});
  

Then run the migration:

php artisan migrate

Step 4: Define Fillable Fields

class Product extends Model
{
    protected $fillable = ['name', 'price', 'description'];
}
  

Step 5: Create Product Controller

php artisan make:controller ProductController --resource

Full controller code:

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

class ProductController extends Controller
{
    public function index()
    {
        $products = Product::latest()->paginate(10);
        return view('products.index', compact('products'));
    }

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

    public function store(Request $request)
    {
        $request->validate([
            'name' => 'required',
            'price' => 'required|numeric',
            'description' => 'nullable',
        ]);

        Product::create($request->only(['name', 'price', 'description']));
        return redirect()->route('products.index')->with('success', 'Product created successfully.');
    }

    public function edit(Product $product)
    {
        return view('products.edit', compact('product'));
    }

    public function update(Request $request, Product $product)
    {
        $request->validate([
            'name' => 'required',
            'price' => 'required|numeric',
            'description' => 'nullable',
        ]);

        $product->update($request->only(['name', 'price', 'description']));
        return redirect()->route('products.index')->with('success', 'Product updated successfully.');
    }

    public function destroy(Product $product)
    {
        $product->delete();
        return redirect()->route('products.index')->with('success', 'Product deleted successfully.');
    }
}
  

Step 6: Add Routes

use App\Http\Controllers\ProductController;
Route::resource('products', ProductController::class);
  

Step 7: Blade Templates

Layout File (resources/views/app.blade.php)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Laravel PostgreSQL CRUD</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
  <div class="container mt-5">
    @yield('content')
  </div>
</body>
</html>
  

Index Page (index.blade.php)

@extends('app')

@section('content')
<h2>Product List</h2>

<a class="btn btn-primary mb-3" href="{{ route('products.create') }}">
  Add Product
</a>

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

<table class="table table-bordered">
  <thead>
    <tr>
      <th>#</th>
      <th>Name</th>
      <th>Price</th>
      <th>Description</th>
      <th>Actions</th>
    </tr>
  </thead>
  <tbody>
    @forelse($products as $product)
      <tr>
        <td>{{ $loop->iteration }}</td>
        <td>{{ $product->name }}</td>
        <td>{{ $product->price }}</td>
        <td>{{ $product->description }}</td>
        <td>
          <a href="{{ route('products.edit', $product) }}" class="btn btn-sm btn-warning">Edit</a>
          <form method="POST" action="{{ route('products.destroy', $product) }}" style="display:inline-block;">
            @csrf
            @method('DELETE')
            <button onclick="return confirm('Are you sure?')" class="btn btn-sm btn-danger">Delete</button>
          </form>
        </td>
      </tr>
    @empty
      <tr><td colspan="5">No products found.</td></tr>
    @endforelse
  </tbody>
</table>

{{ $products->links() }}
@endsection

Create Page (create.blade.php)

@extends('app')

@section('content')
<h2>Add Product</h2>

<form action="{{ route('products.store') }}" method="POST">
  @csrf
  <div class="mb-3">
    <label>Name</label>
    <input name="name" class="form-control" required>
  </div>

  <div class="mb-3">
    <label>Price</label>
    <input name="price" type="number" class="form-control" required>
  </div>

  <div class="mb-3">
    <label>Description</label>
    <textarea name="description" class="form-control"></textarea>
  </div>

  <button class="btn btn-success">Save</button>
  <a href="{{ route('products.index') }}" class="btn btn-secondary">Cancel</a>
</form>
@endsection

Edit Page (edit.blade.php)

@extends('app')

@section('content')
<h2>Edit Product</h2>

<form action="{{ route('products.update', $product) }}" method="POST">
  @csrf
  @method('PUT')

  <div class="mb-3">
    <label>Name</label>
    <input name="name" value="{{ $product->name }}" class="form-control" required>
  </div>

  <div class="mb-3">
    <label>Price</label>
    <input name="price" value="{{ $product->price }}" type="number" class="form-control" required>
  </div>

  <div class="mb-3">
    <label>Description</label>
    <textarea name="description" class="form-control">{{ $product->description }}</textarea>
  </div>

  <button class="btn btn-success">Update</button>
  <a href="{{ route('products.index') }}" class="btn btn-secondary">Cancel</a>
</form>
@endsection

Conclusion

That's it! You've now set up PostgreSQL with Laravel and built a complete CRUD application. This setup is ideal for production applications where PostgreSQL is preferred for its performance and features.

13 Shares

Similar Posts