Migrations
LaravelMigrations are version control for your database. They allow you to define and modify your database schema using PHP instead of raw SQL.
Creating a Migration
Terminal
# Create migration
php artisan make:migration create_posts_table
# Create migration + model at once
php artisan make:model Post -m
# Run migrations
php artisan migrate
# Rollback last batch
php artisan migrate:rollback
# Rollback everything
php artisan migrate:reset
# Rollback + re-run (fresh start)
php artisan migrate:freshWriting a Migration
database/migrations/create_posts_table.php
<?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(); // Auto-increment primary key
$table->foreignId('user_id')
->constrained()
->onDelete('cascade'); // Foreign key
$table->string('title'); // VARCHAR(255)
$table->string('slug')->unique(); // Unique slug
$table->text('body'); // Long text
$table->string('image')->nullable(); // Optional
$table->boolean('published')->default(false);
$table->timestamp('published_at')->nullable();
$table->timestamps(); // created_at + updated_at
$table->softDeletes(); // deleted_at
});
}
public function down(): void
{
Schema::dropIfExists('posts');
}
};
?>Common Column Types
| Method | SQL Type |
|---|---|
$table->id() | BIGINT UNSIGNED AUTO_INCREMENT |
$table->string('name') | VARCHAR(255) |
$table->text('body') | TEXT |
$table->integer('count') | INT |
$table->boolean('active') | TINYINT(1) |
$table->decimal('price', 8, 2) | DECIMAL(8,2) |
$table->timestamp('verified_at') | TIMESTAMP |
$table->json('settings') | JSON |
$table->enum('status', ['active','inactive']) | ENUM |
Modifying Columns
Terminal + PHP
# Create a modification migration
php artisan make:migration add_views_to_posts_table
# In the migration:
public function up(): void
{
Schema::table('posts', function (Blueprint $table) {
$table->integer('views')->default(0)->after('body');
$table->string('meta_description')->nullable()->after('title');
});
}
public function down(): void
{
Schema::table('posts', function (Blueprint $table) {
$table->dropColumn(['views', 'meta_description']);
});
}💡
Never edit existing migrations in production! Always create a new migration to modify tables. Editing old migrations breaks the migration history for the rest of your team.
Test your knowledge!
Take a quiz to reinforce what you learned.