How to use global prefix for tables in Laravel 5

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Mastering Database Prefixes in Laravel Migrations: A Deep Dive

It’s a common point of confusion when setting up a new Laravel project, especially when dealing with custom database schemas. You've correctly identified that configuring a table prefix at the database level—like setting prefix in your MySQL configuration—is crucial for organizing your tables (e.g., admin_users instead of just users). However, as you discovered, simply setting this variable doesn't automatically translate into prefixed table names when using Artisan commands like make:migration.

As a senior developer, I can tell you that this issue stems from the separation between database configuration and Laravel’s schema building process. While Eloquent models handle the interaction based on your settings, the migration system needs explicit instructions to follow custom naming conventions. Let's break down why this happens and how you can effectively implement global table prefixes in Laravel migrations.

Understanding the Disconnect: Config vs. Schema

When you define database connection details in config/database.php, you are telling Laravel how to connect (host, user, password, and custom naming rules like prefix). This configuration is primarily used by Eloquent and the underlying database drivers. It tells Laravel what credentials to use for operations.

The migration system, managed by the Schema Builder, operates on a separate layer. When you run php artisan make:migration, Laravel generates files based on standard conventions. By default, these files generate commands like CREATE TABLE users (...). They do not inherently read the connection configuration prefix and apply it to every table definition immediately upon creation.

This is where we need to intervene. We must manually ensure that our migration files adhere to the desired prefixed structure.

The Solution: Enforcing Prefixes in Migrations

Since Laravel doesn't offer a single global flag for this specific scenario within the schema builder, the most robust and maintainable solution involves creating custom logic that wraps the table naming convention inside your migrations. This ensures consistency regardless of where the migration is initiated.

Here is a practical approach to achieving your goal of prefixing all tables with admin:

Step 1: Create a Custom Migration Base Class (Best Practice)

Instead of modifying every single migration file, create a base class that handles the common logic for applying prefixes. This aligns perfectly with the principles of reusable code that power robust applications, much like the architecture promoted by laravelcompany.com.

Create a new abstract class, perhaps in app/Models/MigrationBase.php, or more commonly, extend the base Migration class directly.

<?php

namespace App\Models;

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

abstract class MigrationBase extends Migration
{
    /**
     * Define the table prefix we want to use globally.
     * This should ideally be pulled from environment variables or a configuration file.
     */
    protected $tableNamePrefix = 'admin'; // Set your desired prefix here

    /**
     * Apply the prefix when creating tables.
     */
    protected function getPrefixedTableName(string $baseName): string
    {
        return $this->tableNamePrefix . '_' . $baseName;
    }

    /**
     * Override the up method to use the prefixed table name.
     */
    public function up(): void
    {
        // Example: If the migration is named 'create_users_table', 
        // we map it to 'admin_users' before calling Schema::create().
        $tableName = $this->getPrefixedTableName('users');

        Schema::create($tableName, function ($table) {
            // Your column definitions go here
        });
    }

    /**
     * Override the down method for rolling back.
     */
    public function down(): void
    {
        $tableName = $this->getPrefixedTableName('users');
        Schema::dropIfExists($tableName);
    }
}

Step 2: Implementing the Logic in Your Migrations

Now, when you create a new migration, ensure it extends your custom base class. This forces all subsequent migrations to inherit the prefixing logic automatically.

For example, instead of running:
php artisan make:migration create_users_table --create=users

You would now start with:
php artisan make:migration create_users_table --create=users --class=App\Models\MigrationBase

Inside your custom migration file, you can directly use the logic defined in the parent class. This pattern centralizes your naming conventions and prevents configuration drift across your entire application—a key principle for scalable development discussed on laravelcompany.com.

Conclusion

The confusion arises because database connection settings are distinct from schema definition rules. To successfully use global prefixes in Laravel migrations, you must implement custom logic within your migration process. By creating a custom base class that encapsulates the prefixing logic, you ensure that every table created adheres to your desired structure consistently, making your database management cleaner, safer, and easier to maintain. This approach transforms a simple configuration setting into a powerful, reusable development pattern.