【问题标题】:Laravel QueryBuilder to Eloquent RelationshipLaravel 查询构建器与雄辩的关系
【发布时间】:2019-12-09 12:59:42
【问题描述】:

更新:

我的结果差不多了,我只想过滤我正在寻找的“当前”学生

我更新的模型:

// 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                  |
+-------------------------+

我的查询生成器

$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 转换为 Eloquent 关系。。 p>

我预期的雄辩的 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,则不显示相关教室

【问题讨论】:

  • 你能展示你的模型和数据库设计吗?
  • @DilipHirapara 我更新了模型结构

标签: laravel eloquent relationship laravel-query-builder


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    模型学生(表名)

    //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']);
    

    【讨论】:

      【解决方案3】:

      看看这个: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 的用户。加入选拔过程,然后加入课堂。

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

      花时间正确地建立关系会让你的生活更轻松。

      【讨论】:

      • 所有表至少有5个字段,我只是总结了解决我的问题的重要内容。进行此更改将无法解决此项目的目的
      • 那不要改了,把student_id加到你的StudentSelectionProcess中?
      • 我的 StudentSelectionProcess 有一个 InscribedStudent,而 InscribedStudent 有 Student,所以如果我添加 student_id 将出现一个保留 cicle
      • Yes 和 No,它将让您直接使用 Student 模型从 StudentSelectionProcess 表中查询数据,而不是通过其他模型。如果您想向学生显示 StudentSelectionProcess 的每个状态,您可以使用 $student = Student::with('hasMany_studentSelectionProcess ')-&gt;find($id); 获取它们
      猜你喜欢
      • 2019-09-14
      • 1970-01-01
      • 2015-03-15
      • 2021-06-17
      • 2016-07-01
      • 2019-06-27
      • 1970-01-01
      • 2020-02-07
      • 2016-02-26
      相关资源
      最近更新 更多