Mahamudul Hasan Rubel
HomeBlogCoursesAboutProjectsSkillsExperiencePhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • Blog
  • Courses
  • About
  • Projects
  • Skills
  • Experience
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
Lesson 4 of the Intermediate Laravel: Real-World Application Patterns course
LaravelJune 25, 20263 min read

Project Board Domain Modeling: Database Design and Eloquent

Learn how to design a scalable database schema for a project board, establish Eloquent relationships, and enforce data integrity with migration constraints.

Laraveldatabase designEloquentmigrationsarchitecturephpbackend

Previously in this course, we explored Repository Pattern Fundamentals to decouple our data access layer from our business logic. In this lesson, we shift our focus to the foundation of that layer: the database schema. We'll design the core entities for our multi-user project board—Users, Projects, and Tasks—and establish the relational integrity required for a production application.

The Problem: Beyond Simple CRUD

When starting a project, it's tempting to throw tables together without considering how they interact. However, a production-grade application requires strict constraints to prevent orphaned records and inconsistent states. We aren't just storing data; we are modeling a domain.

For our project board, we have three primary entities:

  1. Users: The owners and contributors.
  2. Projects: Containers for tasks, owned by a single user (for now).
  3. Tasks: Actionable items belonging to a project.

Designing the Schema with Migrations

We will use Laravel's migration system to enforce these relationships at the database level. While Eloquent handles the "what" in our code, the database schema handles the "how" of data integrity.

1. The Projects Table

A project must belong to a user. We'll use a foreign key constraint to ensure that if a user is deleted, their projects are handled according to our business rules (e.g., onDelete('cascade')).

PHP
Schema::create('projects', function (Blueprint $table) {
    $table->id();
    $table->foreignId('user_id')->constrained()->onDelete('cascade');
    $table->string('name');
    $table->text('description')->nullable();
    $table->timestamps();
});

2. The Tasks Table

Tasks belong to a project. By enforcing the project_id foreign key, we guarantee that no task can exist in a vacuum.

PHP
Schema::create('tasks', function (Blueprint $table) {
    $table->id();
    $table->foreignId('project_id')->constrained()->onDelete('cascade');
    $table->string('title');
    $table->boolean('is_completed')->default(false);
    $table->timestamps();
});

Establishing Eloquent Relationships

Once the schema is defined, we map these relationships in our models. This allows us to traverse the graph of data easily. For a refresher on these basics, see Introduction to Database Relationships in Laravel.

In the Project model:

PHP
public function tasks(): HasMany
{
    return $this->hasMany(Task::class);
}

public function owner(): BelongsTo
{
    return $this->belongsTo(User::class, 'user_id');
}

In the Task model:

PHP
public function project(): BelongsTo
{
    return $this->belongsTo(Project::class);
}

Hands-on Exercise

Your task is to extend the schema to support a "priority" level for tasks.

  1. Create a migration to add an integer column named priority to the tasks table with a default value of 0.
  2. Update your Task model to ensure this field is mass-assignable via the $fillable array.
  3. If you're looking for inspiration on how to manage these attributes, check out Task Manager: Adding Status and Priorities in Laravel.

Common Pitfalls

  • Missing Foreign Keys: Never skip constrained() in your migrations. Without it, you lose database-level integrity, making it possible to have "orphaned" tasks that point to non-existent projects.
  • Over-reliance on Cascades: While onDelete('cascade') is convenient, be careful. In some production systems, you might prefer onDelete('restrict') to prevent accidental deletion of a project that still contains active tasks.
  • Ignoring Indexing: Foreign keys in Laravel automatically create an index, but as your project grows, you'll eventually need to optimize queries further by adding composite indexes.

Recap

We've moved from abstract requirements to a concrete database structure. By using migrations to define foreign key constraints, we've ensured that our data remains consistent. By mapping these in Eloquent, we’ve prepared our application to handle complex queries efficiently. This domain modeling approach is the bedrock of maintainable Laravel applications.

Up next: We will dive into Advanced Eloquent Scopes and Accessors to keep our queries clean and our model data formatted for the API.

Previous lessonRepository Pattern FundamentalsNext lesson Advanced Eloquent Scopes and Accessors
Back to Blog

Similar Posts

LaravelJune 25, 20263 min read

Database Transactions for Data Integrity in Laravel

Learn to use DB::transaction to ensure data integrity in your Laravel apps. Prevent partial state updates by wrapping complex operations in atomic blocks.

Read more
LaravelJune 25, 20263 min read

Task Manager: Completing CRUD Functionality in Laravel

Finalize your Task Manager CRUD functionality by implementing secure edit and delete features. Learn how to maintain data integrity in your Laravel application.

Part of the course

Intermediate Laravel: Real-World Application Patterns

intermediate · Lesson 4 of 58

  1. 1

    Architecting for Maintainability

    3 min
  2. 2

    Implementing the Service Layer

    3 min
  3. 3

    Repository Pattern Fundamentals

    3 min
Read more
LaravelJune 25, 20263 min read

Deleting Records: A Laravel CRUD Guide

Master the final step of CRUD by learning to delete records safely in Laravel. We cover DELETE requests, route naming, and Eloquent deletion.

Read more
  • 4

    Project Board Domain Modeling

    3 min
  • 5

    Advanced Eloquent Scopes and Accessors

    4 min
  • 6

    Service-Oriented Task Management

    3 min
  • 7

    REST API Fundamentals with Sanctum

    3 min
  • 8

    Resource Controllers and API Responses

    3 min
  • 9

    Handling API Validation and Form Requests

    3 min
  • 10

    Implementing Middleware for API Security

    4 min
  • 11

    Database Transactions for Data Integrity

    3 min
  • 12

    Error Handling and Global Exceptions

    3 min
  • 13

    Introduction to Laravel Events and Listeners

    Coming soon
  • 14

    Asynchronous Processing with Queues

    Coming soon
  • 15

    Job Chaining and Batching

    Coming soon
  • 16

    Feature Testing Fundamentals

    Coming soon
  • 17

    Mocking Services and Repositories in Tests

    Coming soon
  • 18

    Testing Events and Jobs

    Coming soon
  • 19

    Database Factories and Seeding

    Coming soon
  • 20

    API Versioning Strategies

    Coming soon
  • 21

    Advanced Request Filtering and Sorting

    Coming soon
  • 22

    Handling File Uploads in REST APIs

    Coming soon
  • 23

    Real-time Notifications with Broadcasting

    Coming soon
  • 24

    Using Observers for Model Lifecycle Hooks

    Coming soon
  • 25

    Implementing Policies for Authorization

    Coming soon
  • 26

    Customizing Authentication Guards

    Coming soon
  • 27

    Rate Limiting API Endpoints

    Coming soon
  • 28

    Eloquent Performance Optimization

    Coming soon
  • 29

    Caching Strategies for Performance

    Coming soon
  • 30

    Using Traits for Code Reuse

    Coming soon
  • 31

    Advanced Dependency Injection with Service Providers

    Coming soon
  • 32

    Command Line Tools with Artisan

    Coming soon
  • 33

    Scheduled Tasks and Cron Jobs

    Coming soon
  • 34

    Integrating Third-Party Services

    Coming soon
  • 35

    Handling Webhooks

    Coming soon
  • 36

    Logging and Monitoring

    Coming soon
  • 37

    Database Migrations Best Practices

    Coming soon
  • 38

    Advanced Testing: Integration Tests

    Coming soon
  • 39

    Testing API Authentication

    Coming soon
  • 40

    Code Quality and Static Analysis

    Coming soon
  • 41

    Project Structure for Large Applications

    Coming soon
  • 42

    Environment and Configuration Management

    Coming soon
  • 43

    Deploying Laravel Applications

    Coming soon
  • 44

    Database Indexing Strategies

    Coming soon
  • 45

    Using Value Objects

    Coming soon
  • 46

    Strategy Pattern for Business Rules

    Coming soon
  • 47

    Advanced Queue Monitoring

    Coming soon
  • 48

    Building a Search API

    Coming soon
  • 49

    Handling Concurrency and Race Conditions

    Coming soon
  • 50

    API Documentation with OpenAPI

    Coming soon
  • 51

    Testing with Test Doubles

    Coming soon
  • 52

    Implementing Multi-Tenancy

    Coming soon
  • 53

    Refactoring Legacy Code

    Coming soon
  • 54

    Using Middleware for Feature Flags

    Coming soon
  • 55

    Building Reusable Packages

    Coming soon
  • 56

    Performance Profiling

    Coming soon
  • 57

    Secure API Design

    Coming soon
  • 58

    Event Sourcing Concepts

    Coming soon
  • View full course