【问题标题】:Laravel 8 collection filter with raw DB query带有原始数据库查询的 Laravel 8 收集过滤器
【发布时间】:2021-09-09 00:04:04
【问题描述】:

我有一个像这样的用户模型和users 表。

此外,我还有一个verification_reminders 表。

first_remindersecond_reminder 字段可以为空。

当用户注册时,会在users 表中插入一条记录,并带有一个null email_verified_at 字段。当他们验证他们的电子邮件时,该字段会填充时间戳。如果他们在没有验证电子邮件的情况下花费太长时间,则会向他们发送提醒。当提醒第一次发出时,一条记录被插入到verification_reminders 表中,first_reminder 填充了时间戳。

如果他们仍然没有验证最后的最终提醒是否已发送,并且second_reminder 字段会填充时间戳。

我需要运行一个查询来选择在users 表中具有null email_verified_at 的用户。

接下来我需要将用户分成两个列表/集合:

  1. users 表中有null email_verified_at 但在verification_reminders 表中没有他们的users_id 记录的用户不会被提醒。
  2. 首先提醒的用户在users 表中有null email_verified_at 并且在verification_reminders 表中记录了他们的user_id,其中填充了first_reminder 字段但null second_reminder

我的尝试


    $users = User::whereNull('email_verified_at')->get();
    
    $users_not_reminded = collect($users)->filter(function($item){
            $reminded = DB::table('verification_reminders')->where('user_id', $item->id)->whereNull('first_reminder')->whereNull('second_reminder');
            
            if($reminded->isEmpty()){
                return $item;
            }
    
    });
    

我能够检索到 $users$users_not_reminded 抛出错误 Call to undefined method Illuminate\Database\Query\Builder::isEmpty()

我什至还没有开始使用$users_first_reminded。我不确定如何继续,因为这个查询对我来说有点太复杂了。我希望有经验的人可以为我指出实现这一目标的更清洁的方法。 谢谢你。顺便说一句,我正在使用 laravel 8。

【问题讨论】:

  • 这里没什么复杂的。 isEmpty() 不是有效的方法。请改用if (!$reminded->exists())

标签: mysql laravel eloquent laravel-8


【解决方案1】:

你没有在 db 查询中调用 first() 或 get()

$reminded = DB::table('verification_reminders')
                 ->where('user_id', $item->id)
                 ->whereNull('first_reminder')
                ->whereNull('second_reminder');

所以你应该调用 first() 或 get() 来代替上面的方法

  $reminded = DB::table('verification_reminders')
                     ->where('user_id', $item->id)
                     ->whereNull('first_reminder')
                    ->whereNull('second_reminder')
                    ->first();

我建议你为verification_reminders表创建模型,然后在用户模型中添加关系

public function verificationReminder(){

   return $this->hasOne(VerificationReminder::class);
}

那你就可以了

 $users = User::whereNull('email_verified_at')
                ->with('verificationReminder')
                ->whereHas('verificationReminder',function ($query){
                    $query->whereNull('first_reminder')
                         ->whereNull('second_reminder');
            }) ->get();

【讨论】:

  • 绝对正确,到目前为止,最好的方法是使用关系并让 Laravel 处理这种方式比创建自定义/原始查询更容易。完全可以解决的关系。最佳答案
  • 这就是工作!
  • 我决定用这个。有效!谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-09
  • 2017-10-04
  • 2021-07-22
  • 1970-01-01
  • 2021-12-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多