laravel / ideas

Issues board used for Laravel internals discussions.
939 stars 28 forks source link

QoL: belongsToMany relationships to detect primary key on models. #2617

Open c3hmke opened 3 years ago

c3hmke commented 3 years ago

I have a table where the primary key is a foreign key to the id on another table (It's a OneToOne child of that table).

migrations:

Schema::create('users', function (Blueprint $table): void {
        $table->increments('id')->primary();
        $table->string('email');
});

Schema::create('clients', function (Blueprint $table): void {
        $table->unsignedInteger('user_id')->primary();
        $table->string('name');
        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});

Schema::create('tests', function (Blueprint $table): void {
        $table->increments('id')->primary();
        $table->string('name');
});

Schema::create('client_test', function (Blueprint $table): void {
        $table->unsignedInteger('client_id')->primary();
        $table->unsignedInteger('test_id')->primary();

        $table->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
        $table->foreign('test_id')->references('id')->on('tests')->onDelete('cascade');
});

If I follow the documentation I would expect that the following would work on the Test model:

public function clients(): BelongsToMany
{
    return $this->belongsToMany(Client::class);
}

Instead when attempting to attach clients to a test I'll get a SQL error stating that the client couldn't be found, and that it's searching for them using the id column (which doesn't exist). Using a Pivot model to define the relationships and then using

public function clients(): BelongsToMany
{
    return $this->belongsToMany(Client::class)->using(TestClientPivot::class);
}

also yields no results.

The following will work:

public function clients(): BelongsToMany
{
    return $this->belongsToMany(Client::class, 'client_test', 'test_id', 'client_id', 'id', 'user_id');
}

In this I'm telling it to use the user_id on the Client instead of just using id but given the documentation I would expect that this is something that's auto-detected using the $primaryKey that I defined on the Client model, failing that, if I implement a Pivot, that it would use the relationships as are defined on the pivot instead of defaulting to id.