beginner
Step 5 of 15
Migrations and Seeders
Laravel Framework
Migrations and Seeders
Migrations are version-controlled database schema definitions that let your team share and synchronize database structure changes. Instead of manually running SQL statements, you define schema changes in PHP classes that can be run forward (migrate) or backward (rollback). Seeders populate your database with test or default data. Together, migrations and seeders ensure every developer and deployment environment has an identical database setup.
Migrations
<?php
// database/migrations/2024_01_15_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()->onDelete('cascade');
$table->string('title');
$table->string('slug')->unique();
$table->text('body');
$table->string('category')->default('general');
$table->boolean('is_featured')->default(false);
$table->timestamp('published_at')->nullable();
$table->timestamps(); // created_at and updated_at
$table->softDeletes(); // deleted_at
$table->index(['category', 'published_at']);
});
}
public function down(): void
{
Schema::dropIfExists('posts');
}
};
// Run migrations
// php artisan migrate
// php artisan migrate:rollback
// php artisan migrate:fresh --seed (drop all + re-run + seed)
Seeders and Factories
<?php
// database/factories/PostFactory.php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
class PostFactory extends Factory
{
public function definition(): array
{
return [
'title' => fake()->sentence(),
'slug' => fake()->unique()->slug(),
'body' => fake()->paragraphs(5, true),
'category' => fake()->randomElement(['tech', 'news', 'tutorial']),
'published_at' => fake()->optional(0.8)->dateTimeBetween('-1 year'),
];
}
}
// database/seeders/DatabaseSeeder.php
namespace Database\Seeders;
use App\Models\User;
use App\Models\Post;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run(): void
{
$admin = User::factory()->create([
'name' => 'Admin User',
'email' => 'admin@example.com',
]);
Post::factory(50)->for($admin)->create();
User::factory(10)->has(Post::factory(5))->create();
}
}
// php artisan db:seed
Pro tip: Usephp artisan migrate:fresh --seedduring development to reset your database to a clean state with test data. In production, never usemigrate:fresh— only runmigrateto apply new migrations. Use factories with Faker to generate realistic test data automatically.
Key Takeaways
- Migrations define database schema changes in PHP, enabling version-controlled database structure.
- Use
php artisan make:migrationto create migrations andphp artisan migrateto run them. - Factories generate fake data for testing using the Faker library.
- Seeders populate the database with initial or test data using factories.
- Never use
migrate:freshin production — it drops all tables.