【问题标题】:Laravel - get last row using whereHasLaravel - 使用 whereHas 获取最后一行
【发布时间】:2018-06-24 20:54:20
【问题描述】:

我正在尝试获取上次用户活动的“created_at”时间, 我有型号 UserUserActivity
我想获取最后一个用户活动并检查该用户的最后一个活动是否是 3 天发送通知,

用户.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
class User extends Model
{
    public function activites()
    {
        return $this->hasMany(Activty::class);
    }

}

Activity.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;

class Activity extends Model
{
    function function user(){
        return $this->belongsTo(User::class);
    }
}

控制器

$latest_activites = User::whereHas("activites",function($query){
            $query->where("created_at",">=",Carbon::now()->subDays(3));
        });
$latest_activites = $latest_activites->get();

【问题讨论】:

  • 您只想为一位用户(当前用户)检查此项?
  • @AlexeyMezenin 不,我想给所有用户发送提醒消息,最后一次活动是 3 天
  • 如果您想获取所有用户在 3 天或更早之前的最后一次活动,请查看我的回答。
  • 但我只想获取最后一个活动,我想获取活动信息,而不仅仅是用户,无论如何要这样做?
  • 但是要发送通知,您仍然需要一个用户实例。那么,您需要让用户只收到一条最新通知吗?还有,关系是hasMany()?

标签: php laravel eloquent


【解决方案1】:

首先,在User模型中创建另一个关系,has to be hasOne to get the latest activity

public function latestActivity()
{
    return $this->hasOne(Activity::class)->latest();
}

然后只加载最近活动超过 3 天的用户

$users = User::whereHas('activites', function($q) {
        $q->where('created_at', '<=', now()->subDays(3));
    })
    ->whereDoesntHave('activites', function($q) {
        $q->where('created_at', '>', now()->subDays(3));
    })
    ->with('latestActivity')
    ->get();

【讨论】:

  • 对不起,我无意中添加了另一个答案,而不是编辑旧答案。此查询将仅获取活动超过 3 天且没有新活动的用户。它还将为每个用户加载最新的活动(每个用户只有一个)。
  • 谢谢,我想这会行得通,我现在试试,是不是循环通过活动而不是用户更好?
  • @Peril 您可以遍历用户并使用$user-&gt;latestActivity 获取最新活动,而无需任何额外的数据库查询。
  • 谢谢 alexey,我还是有问题,我得到了两次用户,我尝试创建 groupBy 但没有成功
  • @Peril 你不能用我的代码让用户两次。只需复制粘贴它,不要使用groupBy。不修改还能用吗?
【解决方案2】:

主要结构:model::latest()-&gt;get()

  $latest_activites = User::with('activites')
                    ->where("activites",function($query){
                     .
                     .
                     .
                     .
            })->latest()->get();

【讨论】:

    【解决方案3】:

    您应该使用基于 created_at 的子查询过滤器同时预先加载用户活动。调用最新的以获取最后的记录,您应该一切顺利。

    $latest_activites = User::with('activites')
                             ->where("activites",function($query){
    
                 $query->where("created_at",">=",Carbon::now()->subDays(3));
    
            })->latest()->get();
    

    【讨论】:

    • 如果您的数据库中没有名为 activities 的列,则在您的第一个 where 子句中,您将收到错误消息。相反,您需要使用whereHas() 而不是使用where
    猜你喜欢
    • 2019-11-17
    • 2015-09-29
    • 2020-07-23
    • 2022-01-03
    • 2023-03-07
    • 2018-10-26
    • 1970-01-01
    • 2018-10-03
    • 1970-01-01
    相关资源
    最近更新 更多