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

Laravel中如何定义合并两个多态外键的Spatie Activitylog统一关联

方案1:轻量集合合并(无需关联查询能力)

如果你只需要获取合并后的活动记录,不需要对activities做预加载、链式查询等操作,直接通过访问器合并两个关联的返回结果即可,实现最简单:

  1. 在User模型中添加访问器方法:
public function getActivitiesAttribute()
{
    // 合并两个关联的查询结果,按创建时间倒序,重设集合索引
    return $this->activitiesBy
        ->merge($this->activitiesOn)
        ->unique('id') // 可选,避免同一条记录同时满足两个条件时重复
        ->sortByDesc('created_at')
        ->values();
}
  1. 如果需要模型序列化(比如接口返回)时自动携带activities字段,在User模型的$appends属性中注册该字段:
protected $appends = ['activities'];

方案2:原生查询实现(支持链式查询、性能更优)

如果需要支持自定义查询条件、单次查询拉取数据,可直接手动构造查询逻辑:
在User模型中添加activities方法:

public function activities()
{
    $userMorphClass = $this->getMorphClass();
    $userId = $this->getKey();

    return \App\Models\Activity::where(function ($query) use ($userMorphClass, $userId) {
        // 匹配作为causer的记录
        $query->where('causer_type', $userMorphClass)
            ->where('causer_id', $userId);
    })->orWhere(function ($query) use ($userMorphClass, $userId) {
        // 匹配作为subject的记录
        $query->where('subject_type', $userMorphClass)
            ->where('subject_id', $userId);
    })->orderByDesc('created_at');
}

调用时直接执行查询即可拿到结果:

// 获取用户所有活动
$activities = $user->activities()->get();
// 支持追加查询条件
$recentActivities = $user->activities()->where('created_at', '>=', now()->subWeek())->get();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 19:45:03