Laravel中如何定义合并两个多态外键的Spatie Activitylog统一关联
方案1:轻量集合合并(无需关联查询能力)
如果你只需要获取合并后的活动记录,不需要对activities做预加载、链式查询等操作,直接通过访问器合并两个关联的返回结果即可,实现最简单:
- 在User模型中添加访问器方法:
public function getActivitiesAttribute() { // 合并两个关联的查询结果,按创建时间倒序,重设集合索引 return $this->activitiesBy ->merge($this->activitiesOn) ->unique('id') // 可选,避免同一条记录同时满足两个条件时重复 ->sortByDesc('created_at') ->values(); }
- 如果需要模型序列化(比如接口返回)时自动携带
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
相关产品推荐
相关产品推荐

