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)可以解决问题,但这只是临时修复:
- 这种写法回避了深层问题,因为枚举直接传入
where的写法在其他场景下是可以正常工作的; - 需要在多处查询枚举的地方修改,不符合代码复用和维护的原则。
补充信息
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
相关产品推荐
相关产品推荐

