Open
Description
API Platform version(s) affected: 4.1.12
Description
When using primary key columns named other than id
(for example prefixed with the table name, author_id
) they get filtered away as "candidates" for route key when you also have a relationship defined.
It happens due to the reject()
here matching it:
https://github.com/api-platform/core/blob/main/src/Laravel/Eloquent/Metadata/ModelMetadata.php#L82-L86
How to reproduce
Modifying the Laravel example from the docs:
diff --git a/app/Models/Author.php b/app/Models/Author.php
index 0b677cd..382e0ed 100644
--- a/app/Models/Author.php
+++ b/app/Models/Author.php
@@ -16,9 +16,10 @@
class Author extends Model
{
protected $fillable = ['name'];
+ protected $primaryKey = "author_id";
public function books(): HasMany
{
- return $this->hasMany(Book::class);
+ return $this->hasMany(Book::class, 'author_id');
}
}
diff --git a/database/migrations/2025_06_02_095333_create_books_table.php b/database/migrations/2025_06_02_095333_create_books_table.php
index 99ade16..1e8f9b2 100644
--- a/database/migrations/2025_06_02_095333_create_books_table.php
+++ b/database/migrations/2025_06_02_095333_create_books_table.php
@@ -17,13 +17,13 @@ public function up(): void
$table->string('title');
$table->text('description');
$table->integer('author_id')->unsigned();
- $table->foreign('author_id')->references('id')->on('authors');
+ $table->foreign('author_id')->references('author_id')->on('authors');
$table->date('publication_date')->nullable();
$table->timestamps();
});
Schema::create('authors', function (Blueprint $table): void {
- $table->id();
+ $table->id('author_id');
$table->string('name');
$table->timestamps();
});
Without books relationship:
$ php artisan r:l --path=api/authors
GET|HEAD api/authors/{author_id}{_format?} ....................................................... _api_/api/authors/{author_id}{._format}_get › ApiPlatform\Laravel › ApiPlatformController
PATCH api/authors/{author_id}{_format?} ..................................................... _api_/api/authors/{author_id}{._format}_patch › ApiPlatform\Laravel › ApiPlatformController
DELETE api/authors/{author_id}{_format?} .................................................... _api_/api/authors/{author_id}{._format}_delete › ApiPlatform\Laravel › ApiPlatformController
GET|HEAD api/authors{_format?} .................................................................... _api_/api/authors{._format}_get_collection › ApiPlatform\Laravel › ApiPlatformController
POST api/authors{_format?} .............................................................................. _api_/api/authors{._format}_post › ApiPlatform\Laravel › ApiPlatformController
With books relationship (Note the missing {author_id}
parameters):
$ php artisan r:l --path=api/authors
GET|HEAD api/authors{_format?} .................................................................... _api_/api/authors{._format}_get_collection › ApiPlatform\Laravel › ApiPlatformController
POST api/authors{_format?} .............................................................................. _api_/api/authors{._format}_post › ApiPlatform\Laravel › ApiPlatformController
PATCH api/authors{_format?} ............................................................................. _api_/api/authors{._format}_patch › ApiPlatform\Laravel › ApiPlatformController
DELETE api/authors{_format?} ............................................................................ _api_/api/authors{._format}_delete › ApiPlatform\Laravel › ApiPlatformController
Possible Solution
Additional Context