首页 > 解决方案 > 如何在laravel中定义多对多关系,其中数据透视表也有多对多关系

问题描述

我有一个包含四个基表的数据库:Classroom、Department、Subject 和 Day。教室仅在某些日子可用,并且一天可以有多个教室可用。因此,这是与作为数据透视表的 AvailableHour 表(和模型)的多对多关系。此表有两个额外字段:可用(true/false)和容量(因为一天的容量可能与基本容量不同)。使事情复杂化的是第二个多对多关系。如果教室在一天内有空,则可能只允许某些部门使用所有科目,仅限一门科目或排除一门科目。这是第二个多对多关系。一个部门可以是许多 availableHours 的一部分,并且一个 availableHour 可以有许多部门。请参阅随附的图像。具有关系的数据库表

如何在 laravel 中定义这种关系,以便我可以查询指定日期允许部门的哪些教室可用?

就像是

Classroom::with(['AvailableHours'=>where(day_id=requested_day and availabel=true),'AvailableHours.AllowDepartments'where(department_id=requested_department)])->get()

(为了便于阅读,闭包被缩短了)。我从一对多的关系开始,但这并没有达到预期的结果。将它们转换为多对多关系和数据透视表和模型会在我要求的那一刻导致错误AvailableHours.AllowedDepartments

Call to undefined relationship [AllowdDepartments] on model [App\Day].

如果我只使用 {Classroom::with('AvailableHours')} 会返回一个教室集合。属性“relations”具有数组 [1] 的 AvailableHours 值,其单个元素是“Day”的集合。

标签: laravel

解决方案


我没有使用多对多关系解决了这个问题,而是使用了一对多。AllowedDpartments 和 AvailableHours 表有自己的模型 Department 模型有许多 AllowedDapertments,但 AllowedDepartment 只有一个 Department。这同样适用于教室和 AvailableHours、Days 和 AvailableHours,最后是 AvailableHours 和 AllowedDepartments。这导致以下关系:

class Day extends Model{
protected $guarded=[];

    public function availableHours(){
        return $this->hasMany(AvailableHour::class);
    }
}

.

class Classroom extends Model{
    public function availableHours()
    {
        //relationship with availableHour which determines the available hours
        return $this->hasMany(AvailableHour::class);
    }
}

.

class AvailableHour extends Model{

//get room this hour belongs to
    public function classroom() {
        return $this->belongsTo(Classroom::class,'number');
    }

//get the day this hour belongs to
    public function day(){
        return $this->belongsTo(Day::class);
    }

//get all the allowedDepartments for this hour
    public function allowedDepartments(){
        return $this->hasMany(AllowedDepartment::class);
    }
}

.

class AllowedDepartment extends Model
{
    //get the availableHour this AllowedDepartment belongs to
    public function availableHour(){
        return $this->belongsTo(AvailableHour::class);
    }
// get the department this AllowedDepartment belongs to
    public function department(){
        return $this->belongsTo(Department::class);
    }
} 

.

class Department extends Model{
//get all the allowedDepartments this Department has
    public function allowedDepartments(){
        return $this->hasMany(AllowedDepartment::class);
    }
}

以下查询返回可供部门使用的教室$department

$classrooms=Classroom::whereHas('AvailableHours.AllowedDepartments.Department',function(Builder $query) use ($department){
        $query->where('id',$department->id);
    })->get('number')`

推荐阅读