我正试图通过Eloquent实现以下目标:
我想查询我的数据库,计算status="waiting"answers"inprogress"的行数,但我遇到了以下问题。如果我运行get(),然后尝试计数,就会被告知我不能对非对象进行计数。如果我尝试在之后运行get(),我会得到以下错误:Undefined property: Laravel'Database'Query::$source
。
这是我的两次尝试:
//get() before
$devs = Dev::todo($user_id)->get(array('id', 'type', 'title', 'source', 'priority', 'status', 'for_user', 'priority', 'desc', 'created_at'));
$devs->num_waiting = $devs->where('status', '=', 'waiting')->count();
$devs->num_inprogress = $devs->where('status', '=', 'inprogress')->count();
//get() after
$devs = Dev::todo($user_id);
$devs->num_waiting = $devs->where('status', '=', 'waiting')->count();
$devs->num_inprogress = $devs->where('status', '=', 'inprogress')->count();
$devs->get(array('id', 'type', 'title', 'source', 'priority', 'status', 'for_user', 'priority', 'desc', 'created_at'));
我的待办事项功能:
public static function todo($user_id) {
$todo = Dev::where('for_user', '=', $user_id)
->where(function($query) {
$query->where('status', '=', 'active')
->or_where('status', '=', 'inprogress')
->or_where('status', '=', 'waiting');
})
->order_by('priority', 'asc')
->order_by('created_at', 'desc');
return $todo;
}
在计算了需要计算的数据后,我如何运行get(),为什么会发生这种情况,有更好的方法吗?
如果不看Eloquent源代码,我猜count()是基于SQL聚合函数count()的。聚合函数返回聚合结果。它们不返回组成聚合的行。
我希望这一行(来自你的代码)能给你计数。
$devs->num_waiting = $devs->where('status', '=', 'waiting')->count();
如果我需要组成计数的行,我会根据应用程序做其中一件事。
- 避免使用count()方法,获取结果集,并计算该集中的项。在我的脑海中,我认为get()返回了一个"collection"类型的对象。查找一个返回集合大小的方法
- 使用相同的where()参数运行第二个查询,并接受并发和竞争条件的后果
这里的问题是get()
返回一个不包含where()
方法的Collection
,因此需要在get()
之前执行where()
。幸运的是,您的get()
似乎正在取代select()
,所以您应该使用它。
试试这个。。。
$devs = Dev::todo($user_id)->select(array('id', 'type', 'title', 'source', 'priority', 'status', 'for_user', 'priority', 'desc', 'created_at'));
现在你应该可以对它进行计数了,但做两次是行不通的,因为第二次计数时间是waiting
和inprogress
。我们可以创建另一个对象来查找其他计数,但它的性能也不太好,因为您基本上运行了三次相同的查询。两个用于计数,一个用于返回实际集合。我要做的是获取您的集合,并在迭代时使用php对其进行计数
$devs = Dev::todo($user_id)
->select(array('id', 'type', 'title', 'source', 'priority', 'status', 'for_user', 'priority', 'desc', 'created_at'))
->get();
$nWaiting = 0;
$nProgress = 0;
foreach($devs as $dev) {
switch($dev->status) {
case 'waiting':
$nWaiting++;
break;
case 'inprogress':
$nProgress++;
break;
default:
break;
}
}
$devs->num_waiting = $nWaiting;
$devs->num_inprogress = $nProgress;
不过,这段代码未经测试,因为我不确定您对todo()
函数做了什么。