Laravel, где ведет себя неожиданно - PullRequest
0 голосов
/ 13 декабря 2018

В моем приложении Laravel 5.6 установлены следующие отношения.

Purchase belongs to many Invoice

Invoice belongs to many Purchase

Invoice belongs to many Payment

Payment belongs to many Invoice

Эти отношения создаются с использованием сводных таблиц.

Я хочу найти только покупок, которые через счета-фактуры имеют платежи, равные 0.

В моем тесте у меня есть одна покупка, к этой покупке я прикрепил два счета, и к каждому из этих счетов я прикрепил один платеж.Один платеж имеет сумму 100, а другой - 0.

Для того, чтобы мой тест прошел, запрос не должен давать результатов, однако он этого не делает, он последовательно возвращает мою покупкусоздал.

Это запрос, который я написал:

Purchase::whereHas('invoices.payments', function ($q) {
   return $q->where('amount', '<=', 0);
})->get();

Я также попытался:

Purchase::whereDoesntHave('invoices.payments', function ($q) {
   return $q->where('amount', '>', 0);
})->get();

Я что-то здесь не так делаю?Я неправильно понимаю возможности WhereHas?

Любая помощь будет принята с благодарностью, спасибо.

Ответы [ 3 ]

0 голосов
/ 13 декабря 2018

Возможно, я не до конца понимаю ваши требования / проблему здесь, но это то, что, я думаю, я понимаю ...

Вы создали 1 Purchase.Имеет 2 Invoice с.Каждый Invoice имеет 1 Payment (1 из 100, 1 из 0 <- технически не платеж). </p>

В своем вопросе вы говорите

Я хочу найти только покупок, которые через счета-фактуры имеют платежи, равные 0.

Но тогда вы жалуетесь, что получили результат ... Когда у вас DO естьпокупка с нулевым платежом.

Чтобы сделать тест немного более "реальным", я бы создал множество Purchase с множеством Invoice с и Payment с и т. Д., Чтобы действительно почувствовать происходящее.

ОБНОВЛЕНИЕ

Рассматривали ли вы отношение hasManyThrough в вашей модели покупки к оплате?вот так

public function payment()
{
    return $this->hasManyThrough(Payment::class, Invoice::class);
}

Тогда, возможно, вы могли бы сделать этот запрос.

Purchase::whereDoesntHave('payment')->get();
0 голосов
/ 13 декабря 2018

Ваш второй подход верен, но whereDoesntHave() не работает должным образом с вложенными отношениями в Laravel 5.6.Эта ошибка была исправлена ​​ в Laravel 5.7.

Вы можете использовать этот обходной путь:

Purchase::whereDoesntHave('invoices', function ($q) {
    $q->whereHas('payments', function ($q) {
        $q->where('amount', '>', 0);
    });
})->get();
0 голосов
/ 13 декабря 2018

Полагаю, вам следует использовать оба метода.

Purchase::whereHas('invoices.payments', function ($q) {
        return $q->where('amount', 0);
    })
    ->whereDoesntHave('invoices.payments', function ($q) {
        return $q->where('amount', '>', 0);
    })
    ->get();

whereHas() принять все покупки с суммой платежа = 0, whereDoesntHave() отбросить покупки с платежами> 0.

...