You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel8如何通过两表关联正确判断用户多课程购买状态

问题背景

现有courses(课程)、admissions(购课记录)两张数据表,业务需求为:用户已购买的课程在前端显示「已录取(Admitted)」标识,未购买的课程展示购买入口及对应价格。
原有代码存在缺陷:仅能识别单条购课记录,同一用户购买多门课程时,仅会标记1门课程为已录取状态,无法正确识别所有已购课程。

原有实现代码

控制器层原有代码

$courses = Course::orderby('id', 'desc')->get();
$admission = Admission::where('users_id', Auth::user()->id)->first() ?: app(Admission::class);            
                
return view('Backend.Student.courses', compact('courses', 'admission'));

Blade模板层原有判断代码

@if( $course->id == $admission->courses_id )
    <li class="list-inline-item">
        <a href="javascript:void(0)" class="btn btn-info btn-sm"><h5 class="p-0 m-0 text-white"> {{ __('Admitted') }}</h5></a>
    </li>
    @if( !empty($admission->status == 'active') )
    <li class="list-inline-item">
        <a href="{{ route('access.course', $course->slug) }}" class="btn btn-warning btn-sm"><h5 class="p-0 m-0 text-white"> {{ __('Continue Course') }}</h5></a>
    </li>
    @endif
@else
    <li class="list-inline-item">
        <a href="{{ route('purchase.course', $course->slug) }}" class="btn btn-info btn-sm"><h5 class="p-0 m-0 text-white"> {{ __('Admission Now') }}</h5></a>
    </li>
    <li class="list-inline-item">{{ __('Price') }}: ৳{{ number_format( $course->price , 0 , '.' , ',' ) }} BDT</li>
@endif
问题根因
  • 控制器层仅通过first()方法获取当前用户的第一条购课记录,没有拉取该用户全部购课数据
  • 模板层判断逻辑仅拿单条购课记录的课程ID做匹配,无法覆盖多门已购课程的匹配场景
  • 原模板中!empty($admission->status == 'active')存在逻辑错误:括号内是布尔判断结果,empty()接收布尔值时判断逻辑不符合预期,会导致状态判断失效
修复方案

第一步:调整控制器逻辑

将取单条购课记录的逻辑,改为取出当前用户所有购课记录的课程ID与对应状态,以键值对集合的形式传递给模板:

$courses = Course::orderby('id', 'desc')->get();
// 取出当前用户所有购课记录,以课程ID为键、购课状态为值生成集合,方便后续快速判断
$userAdmissions = Admission::where('users_id', Auth::user()->id)
    ->pluck('status', 'courses_id');

return view('Backend.Student.courses', compact('courses', 'userAdmissions'));

第二步:调整Blade模板判断逻辑

遍历课程列表时,判断当前课程ID是否存在于用户已购课程集合中即可完成状态匹配:

@if( $userAdmissions->has($course->id) )
    <li class="list-inline-item">
        <a href="javascript:void(0)" class="btn btn-info btn-sm"><h5 class="p-0 m-0 text-white"> {{ __('Admitted') }}</h5></a>
    </li>
    {{-- 直接从集合中读取对应课程的购课状态做判断 --}}
    @if( $userAdmissions->get($course->id) == 'active' )
    <li class="list-inline-item">
        <a href="{{ route('access.course', $course->slug) }}" class="btn btn-warning btn-sm"><h5 class="p-0 m-0 text-white"> {{ __('Continue Course') }}</h5></a>
    </li>
    @endif
@else
    <li class="list-inline-item">
        <a href="{{ route('purchase.course', $course->slug) }}" class="btn btn-info btn-sm"><h5 class="p-0 m-0 text-white"> {{ __('Admission Now') }}</h5></a>
    </li>
    <li class="list-inline-item">{{ __('Price') }}: ৳{{ number_format( $course->price , 0 , '.' , ',' ) }} BDT</li>
@endif

优化说明:使用pluck生成键值对集合的判断方式,时间复杂度为O(n),比循环嵌套判断的性能更高,即使课程和购课记录数据量较大也不会出现性能问题。

内容的提问来源于stack exchange,提问作者Happy Arif

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 07:18:31