You need to enable JavaScript to run this app. Laravel 8 如何用原生查询过滤Collection,实现未验证邮箱用户按提醒状态分类
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 8 如何用原生查询过滤Collection,实现未验证邮箱用户按提醒状态分类

错误原因分析

你现有代码存在两个问题:

  • 语法报错:$reminded 仅构造了查询构造器实例,没有执行查询,本身不支持 isEmpty() 方法,你可以调用 ->exists() 来判断是否存在匹配记录。
  • 逻辑错误:你需要的「未发过提醒的用户」是verification_reminders表不存在对应用户记录,而你写的查询条件是匹配表中存在记录且两个提醒字段都为null的情况,和需求不符。

更简洁的实现方案(推荐)

用Laravel自带的关联查询实现,避免N+1性能问题,代码更易读:

步骤1:给User模型添加关联

在app/Models/User.php中添加一对一关联:

public function verificationReminder()
{
    return $this->hasOne(\App\Models\VerificationReminder::class);
}

如果没有创建VerificationReminder模型,也可以直接用原生查询实现,见下方备选方案。

步骤2:直接查询两类用户

不需要先查所有未验证用户再过滤,直接用whereDoesntHave和whereHas分两次查询即可:

// 1. 未发过提醒的用户
$users_not_reminded = User::whereNull('email_verified_at')
    ->whereDoesntHave('verificationReminder')
    ->get();

// 2. 已发首次提醒的用户
$users_first_reminded = User::whereNull('email_verified_at')
    ->whereHas('verificationReminder', function ($query) {
        $query->whereNotNull('first_reminder')
              ->whereNull('second_reminder');
    })
    ->get();

不使用模型关联的备选方案

如果不想创建提醒表的模型,也可以用whereExists直接写查询:

// 未发过提醒的用户
$users_not_reminded = User::whereNull('email_verified_at')
    ->whereNotExists(function ($query) {
        $query->from('verification_reminders')
              ->whereRaw('user_id = users.id');
    })
    ->get();

// 已发首次提醒的用户
$users_first_reminded = User::whereNull('email_verified_at')
    ->whereExists(function ($query) {
        $query->from('verification_reminders')
              ->whereRaw('user_id = users.id')
              ->whereNotNull('first_reminder')
              ->whereNull('second_reminder');
    })
    ->get();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 06:15:00