Laravel表现异常

时间:2018-12-13 11:01:25

标签: laravel eloquent query-builder

我在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 :(得分: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和许多InvoicePayment等,以真正了解正在发生的事情。

更新

您是否考虑过购买模型与付款之间的“ hasManyThrough”关系?像这样

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

那么也许您可以执行此查询。

Purchase::whereDoesntHave('payment')->get();