Laravel QueryBuilder到雄辩的关系

时间:2019-08-01 00:24:26

标签: laravel eloquent relationship laravel-query-builder

已更新:

我快要取得成绩了,我只是想过滤我正在寻找的“当前”学生

我更新的模型:

// Student.php
public function enrolled()
{
    return $this->belongsToMany('App\Classroom', 'inscribed_students')
    ->with('enrolled_steps.student_process')
    ->whereRaw('start_at >= curdate()');
}

// Classroom.php
public function enrolled_steps()
{
    return $this->hasMany('App\InscribedStudent');
}

// InscribedStudent.php
public function student_process()
{
    return $this->hasMany('App\StudentSelectionProcess');
}

我的输出json:

{
  "id": 1,
  "name": "This is a Student",
  "email": "dborer@example.org",
  "enrolled": [
    {
      "id": 31,
      "name": "This is a Classroom",
      "shift": "Morning",
      "enrolled_steps: [
        {
          "id": 1,
          "student_id": 1,
          "classroom_id": 1,
          "student_process": [
            {
              "id": 1,
              "status": "Approved"   
            } 
          ]
        },
        {
          "id": 2,
          "student_id": 2,
          "classroom_id": 1,
          "student_process": [
            {
              "id": 2,
              "status": "Approved"   
            } 
          ]
        },  
      ] 
    }
  ]
}

当前问题是 enrolled_steps 返回一个数组,但是我过滤了一个学生,我该如何解决这个问题,使它只能让我的当前学生?

我的预期输出:

{
  "id": 1,
  "name": "This is a Student",
  "email": "dborer@example.org",
  "enrolled": [
    {
      "id": 31,
      "name": "This is a Classroom",
      "shift": "Morning",
      "enrolled_steps: {
        "id": 1,
        "student_id": 1,
        "classroom_id": 1,
        "student_process": [
          {
            "id": 1,
            "status": "Approved"   
          } 
        ]
      } 
    }
  ]
}

问题:

我的问题是我必须做多种/硬关系才能显示有关学生的信息。

+--------------------+
| Student            | 
+--------------------+
| id                 | 
| name               |
| email              |  
+--------------------+
+--------------------+
| Classroom          | 
+--------------------+
| id                 | 
| name               |     
| shift              | 
+--------------------+
+--------------------+
| InscribedStudent   | 
+--------------------+
| id                 | 
| student_id         | << Foreign key 
| classroom_id       | << Foreign key 
+--------------------+
+--------------------+
| SelectionProcess   | 
+--------------------+
| id                 | 
| classroom_id       | << Foreign key
| enabled            |
+--------------------+
+-------------------------+
| StudentSelectionProcess | 
+-------------------------+
| id                      | 
| inscribed_student_id    | << Foreign key
| selection_process_id    | << Foreign key
| status                  |
+-------------------------+

我的QueryBuilder

$student = DB::table('students')
            ->join('inscribed_students', 'inscribed_students.student_id', '=', 'students.id')
            ->join('classrooms', 'classrooms.id', '=', 'inscribed_students.classroom_id')
            ->join('selection_processes', 'selection_processes.classroom_id', '=', 'classrooms.id')
            // If exists show, else null
            ->leftjoin('student_selection_processes', 'student_selection_processes.selection_process_id', '=', 'selection_processes.id')
            ->select('students.*', 'classrooms.*', 'student_selection_processes.*')
            ->where([
                ['selection_processes.enabled', 1], // Very important
                ['students.id', $id]
            ])
            ->first();

但是我认为这种方法很混乱,仍然需要重新安排资源,因此我想知道是否有可能将此 Query 转换为雄辩的关系

我期望的雄辩的json结果

{
  "id": 1,
  "name": "This is a Student",
  "email": "dborer@example.org",
  "enrolled": [
    {
      "id": 31,
      "name": "This is a Classroom",
      "shift": "Morning",
      "process: {
        "id": 5,
        "status": "Approved"   
      } 
    }
  ]
}

我可以在教室里上课,但我不知道如何获得这个过程

// StudentController.php - Student controller
$student = Student::with(['enrolled'])
           ->find($id);

// Student.php - Student Model
public function enrolled()
{
    return $this->belongsToMany('App\Classroom', 'inscribed_students');
}

如果可能,如果student_selection_processes为null,请不要显示相关教室

3 个答案:

答案 0 :(得分:0)

我不完全了解您的追求,但是,这样的事情可能会有所帮助:

Student::with(['classroom', 'classroom.selectionProcess', 'classroom.selectionProcess.StudentSelectionProcess'])
    ->having(['classroom.selectionProcess.StudentSelectionProcess'])
    ->find($id);

查看Laravel文档中的嵌套急切加载:https://laravel.com/docs/5.8/eloquent-relationships#eager-loading

答案 1 :(得分:0)

模型学生(表名)

//relation beetween student and classroom
public function StudentClassroom(){
    return $this->belongsToMany('App\Classroom','inscribed_student','student_id','classroom_id')->withTimestamps();
}

//relation beetween Student and InscribedStudent   
public function enrolled(){
    return $this->hasMany('App\InscribedStudent','student_id','id');
}

模型教室(表名)

//relation beetween classroom and student
public function classroomstudents(){
    return $this->belongsToMany('App\Student','inscribed_student','classroom_id','student_id')->withTimestamps();
}


//relation beetween classroom and SelectionProcess
public function selectionclass(){
    return $this->hasMany('App\SelectionProcess','classroom_id','id');
}

模型 SelectionProcess (表名称)

 //relation beetween SelectionProcess and InscribedStudent
public function SelectionProcesInscribedStudent(){
    return $this->belongsToMany('App\InscribedStudent','student_selection_process ','inscribed_student_id','selection_process_id')->withTimestamps();
}

模型 InscribedStudent (表名)

 //relation beetween InscribedStudent and SelectionProcess
public function InscribedStudentSelectionProces(){
    return $this->belongsToMany('App\SelectionProcess','student_selection_process ','selection_process_id','inscribed_student_id')->withTimestamps();
}

//relation beetween InscribedStudent and Student
public function student()
{
    return $this->belongsTo('App\Student','student_id','id');
}

//relation beetween InscribedStudent and classroom
public function classroom()
{
    return $this->belongsTo('App\classroom','classroom_id','id');
}

模型 StudentSelectionProcess (表名称)

//relation beetween StudentSelectionProcess and InscribedStudent
public function inscribed_student()
{
    return $this->belongsTo('App\InscribedStudent','inscribed_student_id','id');
}

//relation beetween StudentSelectionProcess and SelectionProcess
public function selection_process()
{
    return $this->belongsTo('App\SelectionProcess','selection_process_id','id');
}

现在在您的控制器中做

Student::with(['StudentClassroom','enrolled.InscribedStudentSelectionProces']);

答案 2 :(得分:0)

看看这个:https://laravel.com/docs/5.8/eloquent-relationships

这就是我要这样做的方式。将关系重命名为您将在模型中创建的关系。

$student = Student::with(['manyToMany_classrooms_students.hasMany_selectionProcess' => function($query1) use($id) {
    $query1->where('enabled', 1);
    $query1->with(['hasMany_studentSelectionProcess' => function($query2) use($id) {
        $query2->where('student_id', $id);
    }])
}])->find($id);

我也会为此更改您的表格

+--------------------+
| InscribedStudent   | 
+--------------------+
| //id               | << Remove id -> you don't need this for that situation
| student_id         |
| classroom_id       |
+--------------------+

+-------------------------+
| StudentSelectionProcess | 
+-------------------------+
| id                      |
| student_id              | << Refer directly to your student -> InscribedStudent is 
| selection_process_id    |           not a model, it's a pivot table
| status                  |
+-------------------------+

使用它,以正确的关系,您可以找到具有StudentSelectionProcess的用户。加入SelectionProcess,然后加入教室。

Student -> hasMany -> StudentSelectionProcess -> belongsTo -> SelectionProcess -> belongsTo -> Classroom

花时间正确建立人际关系将使您的生活更轻松。