Mahamudul Hasan Rubel
HomeAboutProjectsSkillsExperienceBlogCoursesPhotosContact
Mahamudul Hasan Rubel

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

Navigation

  • Home
  • About
  • Projects
  • Skills
  • Experience
  • Blog
  • Courses
  • 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 16 of the Laravel Fundamentals: From Zero to Your First App course
LaravelJune 25, 20263 min read

Understanding Database Migrations: A Laravel Beginner's Guide

Learn how to manage your database schema using Laravel migrations. Discover how to create, define, and run schema updates for your Task Manager project.

Laraveldatabasemigrationsschemaphpbackend

Previously in this course, we built the UI for our Task Manager in Task Manager: Building the User Interface. Up until now, our "tasks" have been hardcoded arrays in our controller. To build a real application, we need a persistent way to store data.

In this lesson, we’ll move away from static data and start using migrations. Think of migrations as "version control for your database." Instead of manually running SQL queries in a database tool, we write PHP code that describes our table structure, allowing us to share schema changes across teams and environments reliably.

Why Migrations Matter

If you’ve ever worked on a project where you had to manually run ALTER TABLE commands, you know the pain of "it works on my machine but not on production." Migrations solve this by providing a programmatic way to define your database structure. Because these files live in your repository, everyone on your team (and your production server) stays in sync.

Creating Your First Migration

To start, we need a table for our tasks. Laravel provides an Artisan command to generate a migration file. Open your terminal in your project root and run:

Bash
php artisan make:migration create_tasks_table

Laravel will generate a new file in the database/migrations directory. If you look at the filename, you’ll see it’s prefixed with a timestamp—this ensures Laravel executes them in the correct chronological order.

Defining Columns with the Schema Builder

Open the newly created file. You will see two main methods: up() and down(). The up() method is where we define the changes (creating tables, adding columns), and the down() method is where we reverse them (dropping tables, removing columns).

Inside the up() method, use the Schema facade to define your columns:

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

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->id(); #6A9955">// Auto-incrementing primary key
            $table->string('title'); #6A9955">// A VARCHAR column
            $table->text('description')->nullable(); #6A9955">// An optional TEXT column
            $table->boolean('is_completed')->default(false); #6A9955">// A boolean with a default
            $table->timestamps(); #6A9955">// Creates created_at and updated_at columns
        });
    }

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

This code is expressive and readable. We are using the Blueprint object to fluently define our columns. Whether you are using SQLite (which we configured in Setting Up the Local Development Environment) or MySQL, the syntax remains the same.

Running Migrations

Defining the file isn't enough; we need to apply it to the database. Run the following command:

Bash
php artisan migrate

Laravel will look at the migrations table in your database to see which files have already been run. It then executes the up() method of any new files it finds. If you ever need to revert a change, you can use php artisan migrate:rollback.

Hands-on Exercise

  1. Generate a migration for a categories table using php artisan make:migration create_categories_table.
  2. Add a name string column and a slug string column to the up() method.
  3. Run php artisan migrate to apply the change.
  4. Verify the new table exists using your database client or php artisan tinker.

Common Pitfalls

  • Forgetting the down() method: Always define how to undo your changes. If you ever need to rollback, you don't want the process to fail because the down() method is empty.
  • Modifying existing migrations: Once a migration has been pushed to a shared repository, never change it. If you need to add a column later, create a new migration file instead.
  • Ignoring the timestamp: If you manually rename files or edit timestamps, you might break the order in which migrations run. Stick to the generated names.

Mastering migrations and seeders in Laravel for beginners is a rite of passage for any developer. By treating your database schema as code, you ensure your application remains stable as it evolves. If you're interested in advanced techniques, you might eventually explore Laravel online schema change for zero-downtime deployments.

Up next: We will bridge the gap between our database tables and our code by creating an Eloquent model to interact with our new tasks table.

Previous lessonTask Manager: Building the User InterfaceNext lesson Working with Eloquent Models
Back to Blog

Similar Posts

LaravelJune 25, 20263 min read

Task Manager: Displaying Real Database Records

Learn how to display database data in your Laravel Task Manager. We'll connect your Eloquent models to your Blade views to render real, dynamic tasks.

Read more
LaravelJune 25, 20263 min read

Seeding the Database: A Beginner’s Guide to Laravel Factories

Learn how to use database seeding and factories in Laravel to populate your application with realistic dummy data for testing and development.

Part of the course

Laravel Fundamentals: From Zero to Your First App

beginner · Lesson 16 of 52

  1. 1

    Setting Up the Local Development Environment

    4 min
  2. 2

    Installing Laravel and Exploring Directory Structure

    3 min
  3. 3

    Understanding the .env File and Configuration

    3 min
Read more
LaravelJune 25, 20263 min read

Using Blade Layouts and Sections: A Beginner's Guide

Learn how to use Blade layouts and sections to create a DRY, consistent UI for your Laravel application. Stop repeating code and master template inheritance.

Read more
  • 4

    The Laravel Application Lifecycle

    4 min
  • 5

    Initializing the Task Manager Project

    3 min
  • 6

    Defining Basic Web Routes

    4 min
  • 7

    Using Route Parameters

    3 min
  • 8

    Creating Your First Controller

    3 min
  • 9

    Returning Responses and Redirects

    3 min
  • 10

    Task Manager: Implementing the Task List Route

    3 min
  • 11

    Introduction to Blade Templating

    3 min
  • 12

    Using Blade Layouts and Sections

    3 min
  • 13

    Implementing Blade Partials

    4 min
  • 14

    Mastering Blade Directives for Loops and Conditionals

    3 min
  • 15

    Task Manager: Building the User Interface

    3 min
  • 16

    Understanding Database Migrations

    3 min
  • 17

    Working with Eloquent Models

    3 min
  • 18

    Performing Basic CRUD Operations

    3 min
  • 19

    Seeding the Database

    3 min
  • 20

    Task Manager: Displaying Real Database Records

    3 min
  • 21

    Capturing User Input from Forms

    4 min
  • 22

    Introduction to Laravel Validation

    3 min
  • 23

    Customizing Validation Error Messages

    3 min
  • 24

    Using Form Requests for Validation

    3 min
  • 25

    Introduction to Authentication

    4 min
  • 26

    Protecting Routes with Middleware

    Coming soon
  • 27

    Understanding CSRF Protection

    Coming soon
  • 28

    Preventing Mass Assignment

    Coming soon
  • 29

    Task Manager: Securing the Application

    Coming soon
  • 30

    Introduction to Route Model Binding

    Coming soon
  • 31

    Updating Existing Records

    Coming soon
  • 32

    Deleting Records

    Coming soon
  • 33

    Using Named Routes

    Coming soon
  • 34

    Task Manager: Completing CRUD Functionality

    Coming soon
  • 35

    Introduction to Database Relationships

    Coming soon
  • 36

    Querying Related Data

    Coming soon
  • 37

    Handling File Uploads

    Coming soon
  • 38

    Using Flash Messages for User Feedback

    Coming soon
  • 39

    Task Manager: Adding Status and Priorities

    Coming soon
  • 40

    Introduction to Artisan Commands

    Coming soon
  • 41

    Debugging with Laravel Tinker

    Coming soon
  • 42

    Understanding Service Providers

    Coming soon
  • 43

    Using View Composers

    Coming soon
  • 44

    Task Manager: Refactoring for Clean Code

    Coming soon
  • 45

    Introduction to Testing

    Coming soon
  • 46

    Testing Forms and Validation

    Coming soon
  • 47

    Using Database Transactions

    Coming soon
  • 48

    Handling Global Exceptions

    Coming soon
  • 49

    Preparing for Production

    Coming soon
  • 50

    Environment Security Best Practices

    Coming soon
  • 51

    Managing Assets in Production

    Coming soon
  • 52

    Task Manager: Deployment Preparation

    Coming soon
  • View full course