Laravel 连接仅在所有连接的表都包含值时出现

Posted

技术标签:

【中文标题】Laravel 连接仅在所有连接的表都包含值时出现【英文标题】:Laravel joins only appear when all the joined tables contain values 【发布时间】:2021-07-08 07:32:33 【问题描述】:

我有一个课程表表和一个包含content_textscontent_filescontent_videos测验的表。所有表格都与 curriculum 表格以一对多的方式相关,其中一个 curriculum 有许多 content_textscontent_filescontent_videos测验。问题是,当我填写所有 content_textscontent_filescontent_videosquizzes 表格并加入显示时都是,但是我只填一个的时候,我加入的表都没有显示出来。

这是我的 CurriculumDisplayResource

    <?php

namespace App\Http\Resources;

use App\Models\Curriculum;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\DB;

class CurriculumDisplayResource extends JsonResource

    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    




        return [

            'id' => $this->id,
            'title_section' => json_decode($this->title_section),
            'learning_objective'=> json_decode($this->learning_objective),
            'content_detail' =>

                DB::table('curriculums')
                    ->join('content_texts','curriculums.id','=','content_texts.curriculum_id')
                    ->join('content_files','curriculums.id','=','content_files.curriculum_id')
                    ->join('content_videos','curriculums.id','=','content_videos.curriculum_id')
                    ->join('quizzes','curriculums.id','=','quizzes.curriculum_id')
                    ->select('content_texts.title_text','content_texts.text_course',
                        'content_files.title_file','content_files.file_course','content_videos.title_video',
                        'content_videos.video_course',"quizzes.title_quiz",'quizzes.question','quizzes.answer','quizzes.right_answer')
                    ->get(),
            'parent_id' => $this->id,
        ];
    

这是课程控制器

    <?php

    namespace App\Http\Controllers\Course;

    use App\Http\Controllers\Controller;
    use App\Http\Resources\CurriculumDisplayResource;
    use App\Http\Resources\CurriculumResource;
    use App\Models\ContentText;
    use App\Models\Curriculum;
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Auth;
    use Illuminate\Support\Facades\DB;

    class CurriculumController extends Controller
    

        public function index()
        


//            return  CurriculumDisplayResource::collection(
//               DB::table('curriculums')->join('courses','courses.id','=','curriculums.course_id')->select('curriculums.*')->get());
        


        public function store (Request $request)
        

            $c = new Curriculum();
            $c->title_section = json_encode($request->get('title_section'));
            $c->learning_objective = json_encode($request->get('learning_objective'));
            $c->user_id = Auth::id();
            $c->course_id = $request->get('course_id');



            $c->save();

                        return response(new CurriculumDisplayResource($c));


        

        public function show($id)
        

            $curriculum = Curriculum::findOrFail($id);



            return response($curriculum);
        


        public function update(Request $request, $id)
        
            $c = Curriculum::findOrFail($id);
            $c->title_section = json_encode($request->get('title_section'));
            $c->learning_objective = json_encode($request->get('learning_objective'));
            $c->user_id = Auth::id();
            $c->course_id = $request->get('course_id');

            $c->save();

            return response(new CurriculumResource($c));
        

        public function destroy($id)
        
           $c = Curriculum::findOrFail($id);
           $c->delete();

           return response(null,204);
        
    

【问题讨论】:

【参考方案1】:

要从表格课程中获取所有结果,无论它是否有关系数据,您都可以使用left join

无论有没有关系数据,左连接都会从左表获取数据:

 DB::table('curriculums')
                    ->leftJoin('content_texts','curriculums.id','=','content_texts.curriculum_id')
                    ->leftJoin('content_files','curriculums.id','=','content_files.curriculum_id')
                    ->leftJoin('content_videos','curriculums.id','=','content_videos.curriculum_id')
                    ->leftJoin('quizzes','curriculums.id','=','quizzes.curriculum_id')
                    ->select('content_texts.title_text','content_texts.text_course',
                        'content_files.title_file','content_files.file_course','content_videos.title_video',
                        'content_videos.video_course',"quizzes.title_quiz",'quizzes.question','quizzes.answer','quizzes.right_answer')
                    ->get(),

【讨论】:

【参考方案2】:

您可以在 eloquent 中使用关系以更结构化的方式获取所有关系

$curriculums = Curriculum:::whit(['contentTexts', 'contentFils', 'contentVideos', 'quizzes'])->get();

其中'contentTexts', 'contentFils', 'contentVideos', 'quizzes'Curriculum 类中声明的关系的名称

课程::班级

public function contentText()

    return $this->hasMany(ContentVideo::class);

【讨论】:

以上是关于Laravel 连接仅在所有连接的表都包含值时出现的主要内容,如果未能解决你的问题,请参考以下文章

Android-Volley:尝试从真实设备连接时出现 TimeOutError

连接两个具有不同键名的表

Laravel:SQLSTATE [HY000] [2002] 连接被拒绝

为啥在 Access 中使用 UNION ALL 时出现 ODBC 连接失败错误?

尝试连接用户时出现休眠异常 - 字段“用户名”没有默认值

SQL 连接 3 个按最新组值分组的表