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

Laravel如何预加载登录用户专属Thread投票数据并在模型全局生效

实现方案

方案1:全局查询作用域自动追加投票字段(性能最优)

直接在Thread模型的booted方法中注册全局作用域,用户登录状态下查询Thread时会自动追加当前用户的投票类型字段,无需每次手动编写子查询逻辑。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

class Thread extends Model
{
    protected static function booted()
    {
        // 仅登录用户查询时追加投票信息
        if (auth()->check()) {
            static::addGlobalScope('append_user_vote', function (Builder $query) {
                $query->addSelect([
                    // 可按需追加投票类型、投票ID等字段,未投票时值为null
                    'user_vote_type' => Vote::select('type')
                        ->where('user_id', auth()->id())
                        ->whereColumn('thread_id', 'threads.id')
                        ->limit(1)
                ]);
            });
        }
    }

    // 其他模型代码
}

如果个别场景不需要该字段,可手动跳过全局作用域:

Thread::withoutGlobalScope('append_user_vote')->get();

方案2:定义当前用户专属关联关系(灵活度更高)

如果需要获取完整的投票模型实例用于后续操作,可在Thread模型中定义限定当前用户的一对一关联,还可配置自动预加载:

class Thread extends Model
{
    // 配置自动预加载当前用户的投票关联
    protected $with = ['currentUserVote'];

    public function currentUserVote()
    {
        return $this->hasOne(Vote::class)->where('user_id', auth()->id());
    }

    // 其他模型代码
}

使用时直接通过关联属性访问即可:

// 判断是否投票
$hasVoted = !is_null($thread->currentUserVote);
// 获取投票类型
$voteType = $thread->currentUserVote?->type;

个别场景不需要预加载时可跳过:

Thread::without('currentUserVote')->get();

选型建议

  • 仅需要投票状态、类型等基础信息,优先选方案1,单SQL完成查询性能更高
  • 需要对用户的投票记录做更新、删除等操作,优先选方案2,可直接操作关联模型实例

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 13:36:02