【问题标题】:Laravel Eloquent ORM confusionLaravel Eloquent ORM 混淆
【发布时间】:2013-12-28 05:08:44
【问题描述】:

我正在尝试使用 Eloquent 实现以下目标:

我想查询我的数据库,计算 status = 'waiting' 和 '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(),为什么会发生这种情况,有没有更好的方法来做到这一点?

【问题讨论】:

  • Laravel 的 IT 历险记,第 18 集:“Laravel 的雄辩的 ORM 混乱”。 (对不起,我无法抗拒。继续,希望你能找到解决办法!)
  • 是的,不知道怎么称呼它......我来自前端,在 jQuery 中链接是有意义的......对我来说使用对象是有意义的,然后使用该未修改的对象,然后使用 get()... 因为它最初有效。有没有办法$devs = Dev::todo($user_id); $devs->get();

标签: php mysql laravel eloquent laravel-3


【解决方案1】:

不看 Eloquent 源代码,我猜 count() 是基于 SQL 聚合函数 COUNT()。聚合函数返回聚合结果。它们不返回构成聚合的行。

我希望这一行(来自您的代码)能给您计数。

$devs->num_waiting = $devs->where('status', '=', 'waiting')->count();

如果我需要构成计数的行,我会做这些事情之一,具体取决于应用程序。

  1. 避免使用count() 方法,get() 结果集,对集合中的项目进行计数。在我的脑海中,我认为 get() 返回一个“集合”类型的对象。寻找返回集合大小的方法。
  2. 使用相同的 where() 参数运行第二个查询,并忍受并发和竞争条件的后果。

【讨论】:

    【解决方案2】:

    这里的问题是get() 返回一个Collection,它不包含where() 方法,所以你需要在get() 之前执行where()。幸运的是,您的 get() 似乎正在取代 select(),因此您应该改用它。

    试试这个...

    $devs = Dev::todo($user_id)->select(array('id', 'type', 'title', 'source', 'priority', 'status', 'for_user', 'priority', 'desc', 'created_at'));
    

    现在您应该可以对其进行计数,但是执行两次将不起作用,因为第二次计数时间将计数waitinginprogress。我们可以创建另一个对象来查找其他计数,但它的性能也不是很好,因为您基本上运行了 3 次相同的查询。两个用于计数,一个用于返回实际集合。我要做的是获取您的收藏,并在您对其进行迭代时使用 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() 函数做什么。

    【讨论】:

    • 我最终是这样走的,但是我仍然不明白为什么无法运行$devs = Dev::todo($user_id); $devs->get();
    • 我把它添加到我的问题中
    猜你喜欢
    • 2015-07-20
    • 2013-02-12
    • 2016-07-01
    • 2016-09-24
    • 2019-08-01
    • 1970-01-01
    • 2017-01-10
    • 2016-08-21
    • 2018-01-09
    相关资源
    最近更新 更多