Skip to content

Table prefix no longer working in Laravel 12 #56902

@ClemMLD

Description

@ClemMLD

Laravel Version

12.27.1

PHP Version

8.3

Database Driver & Version

PortgresSQL 15

Description

After updating to Laravel 12 from version 11, my table prefix refuse to work when using a model.

The action I'm trying to achieve is to create an entry in my table, which is called "zoho_contacts".
Models\Contact::create([ 'field1' => '1', 'field2' => '2', ]);

My Contact model is just an empty class, extending a custom Model class

<?php

namespace App\DataRepositories\Zoho\Testing\Models;

use App\DataRepositories\Testing\DB;
use App\DataRepositories\Testing\Model as BaseModel;

abstract class Model extends BaseModel
{
  public function getConnection()
      {
          return DB::mockConnectionUsing('pgsql', 'zoho');
      }
}

The mockConnectionUsing method is called from the DB class


namespace App\DataRepositories\Testing;

use Illuminate\Database\Connection;
use Illuminate\Support\Facades\DB as BaseDB;
use Illuminate\Support\Str;

class DB
{
    /** @var array<string, Connection> The cached database connection instances */
    protected static $connections = [];

    /**
     * Get a connection to the testing database for a given existing connection.
     */
    public static function mockConnection(string $name): Connection
    {
        if (isset(static::$connections[$name])) {
            return static::$connections[$name];
        }

        $dbDriver = BaseDB::connection($name)->getDriverName();

        return static::mockConnectionUsing($dbDriver, Str::replace('-', '_', $name));
    }

    /**
     * Get a connection to the testing database for a given driver and with a given table prefix.
     */
    public static function mockConnectionUsing(string $driver, string $prefix): Connection
    {
        if (! in_array($driver, ['pgsql', 'mysql'])) {
            trigger_error("Database mock connection unavailable for driver '{$driver}'", E_USER_ERROR);
        }

        return (clone BaseDB::connection("testing.{$driver}"))->setTablePrefix("{$prefix}_");
    }

    /**
     * Drop tables of a given data repository (by prefix) in the testing database.
     */
    public static function wipeRepository(string $driver, string $prefix): void
    {
        $schema = static::mockConnectionUsing($driver, $prefix)->getSchemaBuilder();
        $allTables = collect($schema->getAllTables())->map->tablename;

        foreach ($allTables as $table) {
            if (Str::startsWith($table, "{$prefix}_")) {
                $schema->drop(Str::after($table, "{$prefix}_"));
            }
        }
    }
}

In this case, what this code is supposed to do is set a prefix to the name of the table for each model using this custom Model class. However, it does not seem to work, as when trying to create an entry, an error is thrown

SQLSTATE[42P01]: Undefined table: 7 ERROR: relation "contacts" does not exist

Here, we can see that the "zoho_" prefix was not set in the table name, thus failing. This is very weird, because the very same code works perfectly on Laravel version 11.45.3. Simply upgrading the laravel/framework version to 12.27.1 is enough to make the error trigger.

What's even weirder is that forcing the table name like this


namespace App\DataRepositories\Zoho\Testing\Models;

use Illuminate\Support\Str;
use App\DataRepositories\Testing\DB;
use App\DataRepositories\Testing\Model as BaseModel;

abstract class Model extends BaseModel
{
    public function getTable()
    {
        return $this->getConnection()->getTablePrefix() . parent::getTable();
    }

    public function getConnection()
    {
        return DB::mockConnectionUsing('pgsql', 'zoho');
    }
}

will result in the following error

SQLSTATE[42P01]: Undefined table: 7 ERROR: relation "zoho_zoho_contacts" does not exist.

Does anyone know why this code suddenly won't work under Laravel 12 ?
Thank you very much for your time.

Steps To Reproduce

With Laravel version 12, creating an entry in a table using a prefix like detailed in the description.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions