【问题标题】:Laravel 8 Paginate Collection (sortBy)Laravel 8 分页集合 (sortBy)
【发布时间】:2021-12-13 15:44:42
【问题描述】:

我尝试在 Laravel 8 中对排序后的集合进行分页,也许有人有想法?

这是我的代码:

$where = Business::where('name', 'LIKE', '%' . $what . '%');
$businesses = $where->get()->sortByDesc(function($business) {
    return $business->totalReviews;
})->paginate(10); // <--- not working.. Collection::paginate not exists

【问题讨论】:

    标签: laravel eloquent collections pagination


    【解决方案1】:

    删除get:

    $businesses = $where->sortByDesc(function($business) {
        return $business->totalReviews;
    })->paginate(10);
    

    【讨论】:

    • 然后我得到这个错误:调用未定义的方法 Illuminate\Database\Eloquent\Builder::sortByDesc()
    【解决方案2】:

    我是这样修的

     $businesses = $where->get()->sortByDesc(function($business) {
         return $business->getTotalReviews();
     });
    
     $businesses = ViewHelper::paginate($businesses, 10);
    

    ViewHelper.class

    <?php
    
        namespace App\Classes;
    
        use Illuminate\Pagination\LengthAwarePaginator;
        use Illuminate\Pagination\Paginator;
        use Illuminate\Database\Eloquent\Collection;
        
        class ViewHelper
        {
            /**
             * Gera a paginação dos itens de um array ou collection.
            *
            * @param array|Collection      $items
            * @param int   $perPage
            * @param int  $page
            * @param array $options
            *
            * @return LengthAwarePaginator
            */
            public static function paginate($items, $perPage = 15, $page = null, $options = [])
            {
                $page = $page ?: (Paginator::resolveCurrentPage() ?: 1);
    
                $items = $items instanceof Collection ? $items : Collection::make($items);
    
                return new LengthAwarePaginator($items->forPage($page, $perPage), $items->count(), $perPage, $page, $options);
            }
        }
    

    【讨论】:

    • 这段代码破坏了使用分页的意义,您仍然从数据库中获取所有业务
    【解决方案3】:

    Paginate 只能在构建器实例上调用(在集合上调用它没有意义,因为您已经拥有所有数据)。但是您正在根据评论计数执行一些逻辑,需要一个模型方法,该方法只能在获取数据后调用。

    因此,您必须重构排序,以便在构建器实例上调用它,以便在分页逻辑发生之前在 SQL 上进行排序。

    withCount('relation') 非常适合此操作,因为它会将特定关系的计数附加到您的查询中,然后您可以根据 SQL 对其进行排序。

    例如,您可以尝试以下方法,其中评论是您拥有许多 Business 模型的关系(可能是 belongsToManyhasMany):

    Business::withCount('reviews')
       ->where('name', 'LIKE', '%' . $what . '%')
       ->orderBy('reviews_count', 'desc')
       ->paginate(10);
    

    Business 模型内部的位置:

    public function reviews()
    {
       return $this->hasMany(Review::class);
    }
    

    【讨论】:

      猜你喜欢
      • 2017-05-03
      • 2019-04-14
      • 1970-01-01
      • 2013-02-20
      • 2019-05-16
      • 2019-03-12
      • 2014-01-30
      • 2015-06-06
      • 2019-10-29
      相关资源
      最近更新 更多