is there any way to get the foreign keys from a laravel model?
I've found that you can get the primary key by using the method getKeyName();
but havn't found any solution to get the foreign keys.
For example class Grades
has the following relations:
public function student()
{
return $this->belongsTo(Student::class, 'student_id', 'id');
}
public function subject()
{
return $this->belongsTo(Subject::class, 'subject_id', 'id');
}
and the following migration:
Schema::create('grades', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('student_id');
$table->unsignedBigInteger('subject_id');
$table->float('grade', 3, 1);
$table->dateTime('graded_at');
$table->timestamps();
$table->foreign('student_id')
->references('id')
->on('students');
$table->foreign('subject_id')
->references('id')
->on('subjects');
$table->unique(['student_id', 'subject_id']);
});
The desired result would be something like:
$grades= new Grades();
return $grades->getForeignKeys();
// desired result
// [
// student_id,
// subject_id
// ]
Is there any way to get all the foreign keys without being able to alter the model?
CodePudding user response:
Eloquent is a pretty magic ORM, it needs nearly no configuration to sync your database to your models but this freedom is at a cost: it doesn't know your database modelisation.
There is no automatic way of getting foreign keys name from a model. But you can make it work by yourself:
Defining relationship like you did returns a relation object, like BelongsTo. Relationship objects have methods to get foreign keys that you defined like getForeignKeyName
So you can do something like this:
$grade = Grade::findOrFail($id);
$fks = [];
$fks [] = $grade->student()->getForeignKeyName();
$fks [] = $grade->subject()->getForeignKeyName();
Another approach would be to add an attribute in your models that stores the foreign keys you want to use, use it as a single source of truth for your relationship definition too, like this:
class Grades extends Model{
protected $foreignKeys = [
'subject' => 'subject_id',
'student' => 'student_id'
];
public function student()
{
return $this->belongsTo(Student::class, $this->foreignKeys['student'], 'id');
}
public function subject()
{
return $this->belongsTo(Subject::class, $this->foreignKeys['subject'], 'id');
}
public function getForeignKeys(){
return array_values($this->foreignKeys);
}
}