Laravel 查询构建器与雄辩的关系
Posted
技术标签:
【中文标题】Laravel 查询构建器与雄辩的关系【英文标题】:Laravel QueryBuilder to Eloquent Relationship 【发布时间】:2019-12-09 12:59:42 【问题描述】:更新:
我的结果差不多了,我只想过滤我正在寻找的“当前”学生
我更新的模型:
// Student.php
public function enrolled()
return $this->belongsToMany('App\Clas-s-room', 'inscribed_students')
->with('enrolled_steps.student_process')
->whereRaw('start_at >= curdate()');
// Clas-s-room.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 Clas-s-room",
"shift": "Morning",
"enrolled_steps: [
"id": 1,
"student_id": 1,
"clas-s-room_id": 1,
"student_process": [
"id": 1,
"status": "Approved"
]
,
"id": 2,
"student_id": 2,
"clas-s-room_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 Clas-s-room",
"shift": "Morning",
"enrolled_steps:
"id": 1,
"student_id": 1,
"clas-s-room_id": 1,
"student_process": [
"id": 1,
"status": "Approved"
]
]
问题:
我的问题是我必须建立多重/硬性关系才能显示有关学生的信息。
+--------------------+
| Student |
+--------------------+
| id |
| name |
| email |
+--------------------+
+--------------------+
| Clas-s-room |
+--------------------+
| id |
| name |
| shift |
+--------------------+
+--------------------+
| InscribedStudent |
+--------------------+
| id |
| student_id | << Foreign key
| clas-s-room_id | << Foreign key
+--------------------+
+--------------------+
| SelectionProcess |
+--------------------+
| id |
| clas-s-room_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('clas-s-rooms', 'clas-s-rooms.id', '=', 'inscribed_students.clas-s-room_id')
->join('selection_processes', 'selection_processes.clas-s-room_id', '=', 'clas-s-rooms.id')
// If exists show, else null
->leftjoin('student_selection_processes', 'student_selection_processes.selection_process_id', '=', 'selection_processes.id')
->select('students.*', 'clas-s-rooms.*', '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 Clas-s-room",
"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\Clas-s-room', 'inscribed_students');
如果可能,如果 student_selection_processes 为 null,则不显示相关教室
【问题讨论】:
你能展示你的模型和数据库设计吗? @DilipHirapara 我更新了模型结构 【参考方案1】:我不完全了解您的需求,但是,这样的事情可能会有所帮助:
Student::with(['clas-s-room', 'clas-s-room.selectionProcess', 'clas-s-room.selectionProcess.StudentSelectionProcess'])
->having(['clas-s-room.selectionProcess.StudentSelectionProcess'])
->find($id);
查看 Laravel 文档中的嵌套预加载:https://laravel.com/docs/5.8/eloquent-relationships#eager-loading
【讨论】:
【参考方案2】:模型学生(表名)
//relation beetween student and clas-s-room
public function StudentClas-s-room()
return $this->belongsToMany('App\Clas-s-room','inscribed_student','student_id','clas-s-room_id')->withTimestamps();
//relation beetween Student and InscribedStudent
public function enrolled()
return $this->hasMany('App\InscribedStudent','student_id','id');
模型教室(表名)
//relation beetween clas-s-room and student
public function clas-s-roomstudents()
return $this->belongsToMany('App\Student','inscribed_student','clas-s-room_id','student_id')->withTimestamps();
//relation beetween clas-s-room and SelectionProcess
public function selectionclass()
return $this->hasMany('App\SelectionProcess','clas-s-room_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 clas-s-room
public function clas-s-room()
return $this->belongsTo('App\clas-s-room','clas-s-room_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(['StudentClas-s-room','enrolled.InscribedStudentSelectionProces']);
【讨论】:
【参考方案3】:看看这个:https://laravel.com/docs/5.8/eloquent-relationships
我就是这样做的。将关系重命名为您将在模型中创建的关系。
$student = Student::with(['manyToMany_clas-s-rooms_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 |
| clas-s-room_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 -> Clas-s-room
花时间正确地建立关系会让你的生活更轻松。
【讨论】:
所有表至少有5个字段,我只是总结了解决我的问题的重要内容。进行此更改将无法解决此项目的目的 那不要改了,把student_id加到你的StudentSelectionProcess中? 我的 StudentSelectionProcess 有一个 InscribedStudent,而 InscribedStudent 有 Student,所以如果我添加 student_id 将出现一个保留 cicle Yes 和 No,它将让您直接使用 Student 模型从 StudentSelectionProcess 表中查询数据,而不是通过其他模型。如果您想向学生显示 StudentSelectionProcess 的每个状态,您可以使用$student = Student::with('hasMany_studentSelectionProcess ')->find($id);
获取它们以上是关于Laravel 查询构建器与雄辩的关系的主要内容,如果未能解决你的问题,请参考以下文章