如何在Eloquent作用域中无需手动关联与原生SQL使用关联模型字段?
更简洁的回访判断实现方式
根据你的需求,分两种场景提供更简洁的实现,避免手动关联表和冗余的原生SQL:
1. 单个 Subscription 模型判断是否需要回访
直接利用模型关联和 Carbon 日期工具,代码直观易读:
// 在 Subscription 模型中添加方法 public function needsFollowUp(): bool { // 先判断间隔设置是否有效 $interval = $this->subscriberType?->days_between_calls; if (is_null($interval) || $interval <= 0) { return false; } // 获取最后一次通话记录 $lastCall = $this->calls()->latest()->first(); // 无通话记录 或 最后一次通话距今超过设置间隔则需要回访 return !$lastCall || $lastCall->created_at->diffInDays(now()) > $interval; }
使用时直接调用:$subscription->needsFollowUp()
2. 批量查询需要回访的 Subscription(作用域写法)
利用 Laravel 的 withMax 获取最后通话时间,结合 joinRelationship 关联订阅类型,减少手动表关联:
// 在 Subscription 模型中添加作用域 public function scopeNeedsFollowUp($query) { return $query->withMax('calls', 'created_at') // 获取每个订阅的最后通话时间 ->joinRelationship('subscriberType') // 利用已定义的 BelongsTo 关联自动关联表 ->where(function ($q) { // 无通话记录 或 最后一次通话超过间隔 $q->whereNull('calls_max_created_at') ->orWhereRaw('DATEDIFF(CURRENT_DATE, calls_max_created_at) > subscriber_types.days_between_calls'); }) ->where('subscriberType.days_between_calls', '>', 0); // 过滤无效间隔设置 }
使用时调用:Subscription::needsFollowUp()->get()
如果你的 Laravel 版本低于 8.x(不支持 joinRelationship),可以替换为 join('subscriber_types', 'subscriptions.subscriber_type_id', '=', 'subscriber_types.id'),但依然比手动写全量关联逻辑简洁。
内容的提问来源于stack exchange,提问作者Jeremy Belolo
相关产品推荐
相关产品推荐

