SyntaxStudy
Sign Up
Laravel Database Migrations and Schema Builder
Laravel Beginner 1 min read

Database Migrations and Schema Builder

Laravel migrations are version-controlled database schema definitions. Each migration file contains an up() method (apply changes) and a down() method (reverse changes). Migrations are run with php artisan migrate and rolled back with php artisan migrate:rollback. The migrations table in your database tracks which migration files have been executed. The Schema facade and its Blueprint class provide a fluent API for creating and modifying tables. Column types include string, integer, bigInteger, text, boolean, date, timestamp, json, and many more. Helper methods like nullable(), default(), unsigned(), unique(), and index() modify column behavior. The id() shortcut creates an auto-incrementing BIGINT primary key column. Foreign key constraints are defined with foreignId() combined with constrained(), which infers the referenced table from the column name (user_id -> users). You can specify cascade behavior with onDelete('cascade') and onUpdate('cascade'). The foreignIdFor(Model::class) method is even more expressive and derives the column name from the model class.
Example
<?php
// database/migrations/2024_01_01_000001_create_posts_table.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('posts', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained()->cascadeOnDelete();
            $table->foreignId('category_id')->nullable()->constrained()->nullOnDelete();
            $table->string('title');
            $table->string('slug')->unique();
            $table->text('body');
            $table->string('status')->default('draft');
            $table->boolean('is_featured')->default(false);
            $table->json('meta')->nullable();
            $table->timestamp('published_at')->nullable();
            $table->softDeletes();
            $table->timestamps();

            $table->index(['status', 'published_at']);
        });
    }

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