Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling ->index() after constrained() sets foreign key name to 1 #53768

Closed
carestad opened this issue Dec 5, 2024 · 3 comments
Closed

Calling ->index() after constrained() sets foreign key name to 1 #53768

carestad opened this issue Dec 5, 2024 · 3 comments

Comments

@carestad
Copy link
Contributor

carestad commented Dec 5, 2024

Laravel Version

11.34.2

PHP Version

8.4.1

Database Driver & Version

Postgres 16

Description

In migrations, chaining ->index() on a foreignId(), foreignUlid() or foreignUuid() column after ->constrained(), will lead to the foreign key being named 1 instead of <table_name>_<column_name>_foreign as expected.

Steps To Reproduce

In a fresh application, if I add a migration that contains this:

Schema::create('foos', function (Blueprint $table) {
    $table->ulid('id')->primary();
});

Schema::create('example', function (Blueprint $table) {
    $table->foreignUlid('foo_id')->nullable()->constrained('foos')->nullOnDelete()->index();
});

The foreign key is just named 1.

If I change the migration and call ->index() right after foreignUlid() instead, the foreign key is named example_foo_id_foreign instead. Example:

Schema::create('foos', function (Blueprint $table) {
    $table->ulid('id')->primary();
});

Schema::create('example', function (Blueprint $table) {
    $table->foreignUlid('foo_id')->index()->nullable()->constrained('foos')->nullOnDelete();
});

I have only tested this with Postgres, not sure if it affects MySQL or other DB types.

@carestad carestad changed the title Calling ->index() after constrained() sets index name to 1 Calling ->index() after constrained() sets foreign key name to 1 Dec 5, 2024
@crynobone
Copy link
Member

public function references($column, $indexName = null)
{
return $this->blueprint->foreign($this->name, $indexName)->references($column);
}

Wouldn't using constrained() already called Blueprint::foreign() and add indexing?

@carestad
Copy link
Contributor Author

carestad commented Dec 6, 2024

public function references($column, $indexName = null)
{
return $this->blueprint->foreign($this->name, $indexName)->references($column);
}

Wouldn't using constrained() already called Blueprint::foreign() and add indexing?

It adds a foreign key, but in postgres, i don't think a foreign key is an index. In mysql and mariadb it also works as an index (or it adds an index as well when adding foreign keys). As per https://stackoverflow.com/a/970605/1223692 (although not particularly new that SO thread.)

Either way, it is the naming of said index that has a weird behaviour here

@crynobone
Copy link
Member

Either way, it is the naming of said index that has a weird behaviour here

Yes it seems weird, but calling constraints() return ForeignKeyDefinition definition as no longer an instance of ForeignIdColumnDefinition when you run $table->foreignUlid('foo_id') therefore changing index() here cause it to call index(true) due it being 2 different class.

<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('foos', function (Blueprint $table) {
            $table->ulid('id')->primary();
        });

        Schema::create('example', function (Blueprint $table) {
            tap($table->foreignUlid('foo_id')->nullable(), function (ForeignIdColumnDefinition $column) {
                $column->constrained('foos')->nullOnDelete();
            })->index();
        });
    }
}

CleanShot 2024-12-06 at 17 44 33

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants