使用 Eloquent 查询相关 table 数据

Querying related table data with Eloquent

我在尝试从基于相关 table 的模型中获取记录时遇到问题。

我有两个 table,一个叫 leads,一个叫 recycle_logs,我的应用基本上会在 leads table 中发送相同的记录就像一个月一次,当它这样做时,我会在 recycle_logs.

中存储一条新记录

问题是我需要 select 所有 leads 具有特定的 campaign_id 值并且具有不同于 [=21= 的特定 status ],到目前为止一切顺利,现在的问题是只有当它们没有任何关联的 recycleLogs 或者最后一个 recycleLog 与特定的 lead 关联时我才需要获取它们例如比 30 天前早。

我目前的看起来有点像这样。

    $leads = $this->leadModel->where(Lead::CAMPAIGN_ID, $this->campaignID)
                ->where(Lead::DUPLICATED, Lead::DUPLICATED_NO)
                ->where(Lead::LEAD_STATUS, "!=" ,Lead::LEAD_STATUS_INVALID)
                ->orderBy(Lead::CREATED_AT, 'desc')
                ->with(
                    ['leadRecyclingLog' => function($query) {
                        $query->where(LeadRecyclingLog::CREATED_AT, '<', (new Carbon())->subDays($this->configRecyclingDays))
                            ->orWhere(LeadRecyclingLog::ID, null);
                    }]
                )
                ->get();

我到底做错了什么?无论我添加还是删除,它总是 select 相同数量的记录 recycleLogs

我已经设法通过原始 SQL 查询完成了它,我将在下面 post 以防它对任何人有帮助,我仍然想知道如何在Eloquent/Query 生成器。

SELECT * FROM `leads` LEFT JOIN `lead_recycling_logs` ON `leads`.`guid` = `lead_recycling_logs`.`original_lead_guid` WHERE `leads`.`campaign_id` = :campaignID AND `leads`.`duplicated` = 0 AND `leads`.`lead_status` != :invalidStatus AND (`lead_recycling_logs`.`id` IS NULL OR `lead_recycling_logs`.`created_at` < :recyclingDate) ORDER BY `leads`.`created_at` DESC

试试这个:

$leads = $this->leadModel->where(Lead::CAMPAIGN_ID, $this->campaignID)
    ->where(Lead::DUPLICATED, Lead::DUPLICATED_NO)
    ->where(Lead::LEAD_STATUS, "!=" ,Lead::LEAD_STATUS_INVALID)
    ->orderBy(Lead::CREATED_AT, 'desc')
    ->where(function($q) {
        $q->whereHas('leadRecyclingLog', function($q) {
            $q->where(LeadRecyclingLog::CREATED_AT, '<', (new Carbon())->subDays($this->configRecyclingDays));
        })
        ->orWhereHas('leadRecyclingLog', '<', 1); // Where count of the relationship is smaller than 1
    })->get();

我假设查询的第一部分运行良好(直到建立关系)。

您要查找的是 ->whereHas(relationship),而不是 ->with(relationship)->with(relationship)会将关联的结果附加到原始模型中(对原始模型的查询不会受到->with()的影响)。 ->whereHas(relationship) 按条件筛选原始模型。

通过@devk 的帮助得到它的工作

    $leads = $this->leadModel->where(Lead::CAMPAIGN_ID, $this->campaignID)
        ->where(Lead::DUPLICATED, Lead::DUPLICATED_NO)
        ->where(Lead::LEAD_STATUS, "!=" ,Lead::LEAD_STATUS_INVALID)
        ->orderBy(Lead::CREATED_AT, 'desc')
        ->where(function($q) {
            $q->whereHas('leadRecyclingLog', function($q) {
                $q->where(LeadRecyclingLog::CREATED_AT, '<', (new Carbon())->subDays($this->configRecyclingDays));
            })
                ->doesntHave('leadRecyclingLog', 'or');
        })->get();