我在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的功能?
非常感谢您的帮助。
答案 0 :(得分:2)
您的第二种方法是正确的,但是whereDoesntHave()
在Laravel 5.6中不适用于嵌套关系。此错误已在Laravel 5.7中fixed。
您可以使用以下解决方法:
Purchase::whereDoesntHave('invoices', function ($q) {
$q->whereHas('payments', function ($q) {
$q->where('amount', '>', 0);
});
})->get();
答案 1 :(得分:0)
我想,您应该同时使用两种方法。
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的购买。
答案 2 :(得分:0)
也许我不能完全理解您的要求/这里的问题,但这就是我的理解...
您创建了1个Purchase
。
它有2个Invoice
。
每个Invoice
都有1个Payment
(100个中的1个,0中的1个-从技术上讲不是付款)。
在您的问题中您说
我想找到仅只个通过发票进行了付款的购买 是0。
但是随后,您抱怨得到了结果。。。 DO 进行零支付购买。
为了使测试更加“真实”,我将创建许多Purchase
和许多Invoice
和Payment
等,以真正了解正在发生的事情。
更新
您是否考虑过购买模型与付款之间的“ hasManyThrough”关系?像这样
public function payment()
{
return $this->hasManyThrough(Payment::class, Invoice::class);
}
那么也许您可以执行此查询。
Purchase::whereDoesntHave('payment')->get();