简体   繁体   中英

Laravel through model relationships

I have 3 tables with this order:

  1. School it has -> id
  2. SchoolSemester it has -> school_id
  3. SemesterClass it has -> semester_id

Now I am trying to make relation between School and SemesterClass in order to get list of classes of each school as well as name of schools in each class.

based on documentation i have this relationships:

school model

class School extends Model
{
    public function semesters() {
        return $this->hasMany(SchoolSemester::class);
    }

    public function classes() {
        return $this->hasManyThrough(SemesterClass::class, SchoolSemester::class);
    }
}

SchoolSemester model

class SchoolSemester extends Model
{
    public function school() {
        return $this->belongsTo(School::class);
    }

    public function classes() {
        return $this->hasMany(SemesterClass::class, 'semester_id', 'id');
    }
}

SemesterClass model

class SemesterClass extends Model
{
    public function school() {
        return $this->hasOneThrough(School::class, SchoolSemester::class, 'school_id', 'id');
    }

    public function semester() {
        return $this->belongsTo(SchoolSemester::class, 'semester_id', 'id');
    }
}

Controller

public function show($id)
{
    $class = SemesterClass::with(['school', 'teacher', 'teacher.user', 'students'])->findOrFail($id);
    dd($class);
    //return view('admin.Classes.show', compact('class'));
}

Results

一

Any idea?

Your intermediate table is school_semester , laravel will find the foreign_key school_semester_id by default, however, your foreign_key is semester_id , so you need to specify the foreign_key in hasManyThrough :

    public function classes() {
        return $this->hasManyThrough(
            SemesterClass::class, 
            SchoolSemester::class
            'school_id', // Foreign key on school_semesters table...
            'semester_id', // Foreign key on classes table...
            'id', // Local key on schools table...
            'id' // Local key on school_semesters table...
        );
     }

And change your hasOneThrough code like this:

 public function school() {
        return $this->hasOneThrough(
             School::class, 
             SchoolSemester::class, 
             'id',
             'id',
             'semester_id',
             'school_id' );
    }

Another Solution:

Because the reverse is just the concatenation of two BelongsTo relationships, so you can just put the belongsTo in SchoolSemester and School Model. And get the relationship like this:

SemesterClass::with(['semester.school'])

Or you can define a mutator in SemesterClass Model:

protected $appends = ['school'];

public function getSchoolAttribute() {
    return $this->semester->school;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM