只用关系中的第一次迭代查找总数

时间:2014-04-21 18:50:24

标签: php laravel eloquent

在这种情况下,我有一个Ticket模型和一个TicketReply模型。

我可以使用$ticket->replies获取对故障单的所有回复。

考虑到票证或回复的状态1或3意味着其状态是开放/未解决的,这就是我目前如何找到以 Eloquent 方式打开票证总数的方式。

$tickets = Ticket::all();

$tickets_open = 0;

foreach($tickets as $t)
{
    $tickets_open++;

    if(($t->replies()->first()->status == 2) || ($t->status == 2))
    {
        $tickets_open--;
    }
}

return $tickets_open;

Eloquent 是否有更有效的方法?

因为它是一个查询将为每次迭代运行。

如果没有,我可以将$tickets转换为数组并迭代它。

更新

$t->replies()->first()->status导致1+N有或没有急切加载。

我改为$t->replies->first()->status1+N消失了。我相信一个新手的错误。

2 个答案:

答案 0 :(得分:0)

您可以使用Eager Loading来减少查询次数。

$tickets = Ticket::with('replies')->get();

执行此操作,您将最终运行两个SQL查询,而不是运行1+N个查询:

select * from Tickets

select * from TicketReplies where ticket_id in (1, 2, 3, 4, 5, ...)

答案 1 :(得分:0)

虽然这对我来说有点混乱,但我相信你可能会尝试这样的事情:

$openTickets = Reply::where('status', 2)->count();

也许是这样的:

$tickets = Ticket::whereHas('replies', function($query) {
    $query->where('status', 2);
})->with('replies')->get();

然后数:

$t = 0;
$tickets->fetch('replies')->each(function($i) use (&$t){
    $t += count($i);
});
dd($t); // total

我可能错了,但我猜想可以这样做。

P / S:请让我知道更新。