Home > Mobile >  How to get foreign keys from laravel model?
How to get foreign keys from laravel model?

Time:11-18

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);
    }
}
  • Related