pfrug / composite-key
Support for composite primary keys in Laravel Eloquent models.
v1.0.0
2025-06-03 20:20 UTC
Requires
- php: ^8.2
Requires (Dev)
- orchestra/testbench: ^8.0
- phpunit/phpunit: ^10.0
README
pfrug/composite-key
provides support for composite primary keys in Eloquent models.
Laravel does not natively support composite primary keys, as mentioned in the official documentation:
https://laravel.com/docs/12.x/eloquent#composite-primary-keys
This package offers a lightweight and flexible solution to enable composite key support for:
find()
andfindOrFail()
methodssave()
anddelete()
operations- Basic Eloquent relationships:
hasManyComposite()
belongsToComposite()
Installation
composer require pfrug/composite-key
Usage
Model Setup
use Pfrug\CompositeKey\Traits\HasCompositeKey; use Illuminate\Database\Eloquent\Model; class ShipmentHeader extends Model { use HasCompositeKey; protected array $compositeKey = ['company_code', 'shipment_number']; }
Finding Records
ShipmentHeader::find(['COMP001', 'SHIP123']); ShipmentHeader::findOrFail(['COMP001', 'SHIP123']);
Relationships
hasManyComposite
$this->hasManyComposite( RelatedModel::class, ['foreign_key_1', 'foreign_key_2'], ['local_key_1', 'local_key_2'] );
belongsToComposite
$this->belongsToComposite( RelatedModel::class, ['foreign_key_1', 'foreign_key_2'], ['owner_key_1', 'owner_key_2'] );
Example: Composite Relationships in Practice
Student.php
class Student extends Model { public function enrollments() { return $this->hasMany(Enrollment::class, 'student_id'); } }
Course.php
class Course extends Model { public function enrollments() { return $this->hasMany(Enrollment::class, 'course_id'); } }
Enrollment.php
use Pfrug\CompositeKey\Models\CompositeModel; class Enrollment extends CompositeModel { protected $compositeKey = ['student_id', 'course_id']; public function student() { return $this->belongsTo(Student::class, 'student_id'); } public function course() { return $this->belongsTo(Course::class, 'course_id'); } public function grades() { return $this->hasManyComposite( Grade::class, ['student_id', 'course_id'], ['student_id', 'course_id'] ); } }
Grade.php
use Pfrug\CompositeKey\Models\CompositeModel; class Grade extends CompositeModel { protected $compositeKey = ['student_id', 'course_id']; public function enrollment() { return $this->belongsToComposite( Enrollment::class, ['student_id', 'course_id'], ['student_id', 'course_id'] ); } }
Sample Usage
// Retrieve record with composite key $enrollment = Enrollment::find([1, 1]); // Update record $enrollment->grade = 'B+'; $enrollment->save(); // Access belongsTo relation echo $enrollment->student->name; // Access hasManyComposite relation foreach ($enrollment->grades as $grade) { echo $grade->value; } // Access belongsToComposite relation from Grade $grade = Grade::first(); echo $grade->enrollment->course_id;
Compatibility
- Laravel 10+
- PHP 8.2+
License
MIT