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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 14:15:38