Skip to content

addForeignkey() without a constraint/name creates a constraint, which has a integer name #1040

@LordSimal

Description

@LordSimal

So this is a weird issue.

I have migrations which add a foreign key like so (the old fashioned way)

->addForeignKey('staff_member_id', 'staff_members', ['id'], ['delete'=> 'CASCADE'])

which then created the table for tests fine, but causes problems combined with

ConnectionHelper::dropTables('test');

when used in tests/bootstrap.php

Why? Because the method to drop all tables uses the constraint names to get its details and throws this error

Error in bootstrap script: TypeError:
Cake\Database\Schema\TableSchema::getConstraint(): Argument #1 ($name) must be of type string, int given, called in /Users/kevin/Documents/sunlime/alfred/vendor/cakephp/cakephp/src/Database/Schema/MysqlSchemaDialect.php on line 1013
#0 /Users/kevin/Documents/sunlime/alfred/vendor/cakephp/cakephp/src/Database/Schema/MysqlSchemaDialect.php(1013): Cake\Database\Schema\TableSchema->getConstraint(1)
#1 /Users/kevin/Documents/sunlime/alfred/vendor/cakephp/cakephp/src/TestSuite/ConnectionHelper.php(105): Cake\Database\Schema\MysqlSchemaDialect->dropConstraintSql(Object(Cake\Database\Schema\TableSchema))
#2 /Users/kevin/Documents/sunlime/alfred/tests/bootstrap.php(56): Cake\TestSuite\ConnectionHelper::dropTables('test')
#3 /Users/kevin/Documents/sunlime/alfred/vendor/phpunit/phpunit/src/TextUI/Configuration/BootstrapLoader.php(61): include_once('/Users/kevin/Do...')
#4 /Users/kevin/Documents/sunlime/alfred/vendor/phpunit/phpunit/src/TextUI/Configuration/BootstrapLoader.php(36): PHPUnit\TextUI\Configuration\BootstrapLoader->load('/Users/kevin/Do...')
#5 /Users/kevin/Documents/sunlime/alfred/vendor/phpunit/phpunit/src/TextUI/Application.php(132): PHPUnit\TextUI\Configuration\BootstrapLoader->handle(Object(PHPUnit\TextUI\Configuration\Configuration))
#6 /Users/kevin/Documents/sunlime/alfred/vendor/phpunit/phpunit/phpunit(104): PHPUnit\TextUI\Application->run(Array)
#7 {main}

as this method expects a string being passed down for the constraint name, but the generated constraint name is 1 as an integer for me.

Image

Technically this would be fixable by adjusting constraints() to not use array keys and instead actually get the name from the constraint object like so

public function constraints(): array
{
    return array_map(function ($constraint) {
        return $constraint->getName();
    }, $this->_constraints);
}

but I'd rather fallback to some auto generated constraint name in migrations.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions