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

Laravel中使用Enum进行Where查询时的不一致行为求助

问题:Laravel枚举查询在不同赛季数据下的不一致问题

项目背景

我正在开发一个模拟赛车圈速赛网站,参赛者可为特定赛季的特定赛事提交不限数量的圈速,管理员可批准或拒绝这些圈速,每位参赛者最快的已批准圈速会显示在该赛事的排行榜上。

我使用Snowflake ID替代自增ID或GUID,通过第三方包生成。

核心代码实现

圈速状态枚举

enum LapTimeStatus: int
{
    case SUBMITTED = 0;
    case APPROVED = 1;
    case DENIED = 2;
}

LapTime 模型

class LapTime extends Model
{
    use HasFactory, Snowflake;

    protected $casts = [
        'status' => LapTimeStatus::class,
    ];

    public function round(): BelongsTo
    {
        return $this->belongsTo(Round::class);
    }
}

Round 模型

class Round extends Model
{
    use HasFactory, Snowflake;  

    public function times(): HasMany
    {
        return $this->hasMany(LapTime::class);
    }

    public function timesForLeaderboard(): array
    {
        $times = $this->times()
                      ->with('user')
                      ->orderBy('lap_time')
                      ->where('status', LapTimeStatus::APPROVED)
                      ->get();

        return $times->unique('user_id')->values()->toArray();
    }
}

timesForLeaderboard方法的作用是:获取当前赛事所有已批准的圈速,按毫秒级圈速值排序,最终确保每位用户仅保留一条最快圈速记录。

异常现象

->where('status', LapTimeStatus::APPROVED)这行查询代码出现了不一致的行为:

  • 在第一个赛季的赛事数据中,查询完全正常,能正确返回已批准的圈速;
  • 在其他赛季的赛事中,尽管明确存在已批准的圈速记录,该语句却始终返回0个模型实例。

将代码改为->where('status', (string) LapTimeStatus::APPROVED->value)可以解决问题,但这只是临时修复:

  1. 这种写法回避了深层问题,因为枚举直接传入where的写法在其他场景下是可以正常工作的;
  2. 需要在多处查询枚举的地方修改,不符合代码复用和维护的原则。

补充信息

LapTime表的迁移代码如下:

return new class extends Migration {
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('lap_times', function (Blueprint $table) {
            $table->unsignedBigInteger('id')->primary();
            $table->foreignId('user_id')->constrained()->cascadeOnDelete();
            $table->foreignId('round_id')->constrained()->cascadeOnDelete();
            $table->unsignedBigInteger('lap_time');
            $table->string('video_url');
            $table->unsignedInteger('status')->default(LapTimeStatus::SUBMITTED->value);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('lap_times');
    }
};

请问:在几乎相同的环境下,是什么原因导致了这种查询结果不一致的情况?


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 16:35:22