【问题标题】:Laravel alternative to paginate on collection?Laravel 替代收集分页?
【发布时间】:2019-12-02 17:44:33
【问题描述】:

在我的网站上,我有提交,提交可以有 cmets。

评论可以有赞成票和反对票,从而导致评论的总“得分”。

在本例中,在将 cmets 传递给视图之前,我按分数对它们进行排序。

$comments = Comment::where('submission_id', $submission->id)->where('parent_id', NULL)->get();

$comments = $comments->sortByDesc(function($comment){
    return count($comment['upvotes']) - count($comment['downvotes']);
});     

这很好用。评论的分数越高,它的排序就越高。

但是,我想对这些结果进行分页。

如果我使用->paginate(10) 而不是get(),则以下sortByDesc 只会对这10 个结果进行排序。

所以从逻辑上讲,我想在sortByDesc 之后添加分页器,如下所示:

$comments = $comments->sortByDesc(function($comment){
    return count($comment['upvotes']) - count($comment['downvotes']);
})->paginate(10);   

但是这会返回错误:

方法 Illuminate\Database\Eloquent\Collection::paginate 没有 存在。

正如预期的那样。

我的问题是,在这种情况下使用 paginate 的替代方法是什么?

编辑:

尝试@party-ring 的响应(并切换双引号和单引号)时,出现以下错误:

SQLSTATE[42000]:语法错误或访问冲突:1064 你有一个 SQL 语法错误;检查与您对应的手册 MariaDB 服务器版本,用于在 '["upvotes"]) 附近使用正确的语法 - count($comment["downvotes"]) desc limit 10 offset 0' at line 1 (SQL: select * from comments where submission_id = 1 and parent_id is 按计数为空($comment["upvotes"]) - count($comment["downvotes"]) desc limit 10 offset 0)

【问题讨论】:

    标签: laravel


    【解决方案1】:

    您正在尝试在获取后进行分页,我在我的网站上尝试的解决方案是这个并且它有效

    $users = User::where('votes', '>', 100)->get();
    
    $page = Input::get('page', 1); // Get the ?page=1 from the url
    $perPage = 15; // Number of items per page
    $offset = ($page * $perPage) - $perPage;
    
    return new LengthAwarePaginator(
        array_slice($users->toArray(), $offset, $perPage, true), // Only grab the items we need
        count($users), // Total items
        $perPage, // Items per page
        $page, // Current page
        ['path' => $request->url(), 'query' => $request->query()] // We need this so we can keep all old query parameters from the url
    );
    

    【讨论】:

    • 当你在你的 url 中使用 laravel 分页时,你会得到查询 ?page=1 取决于你正在寻找的页面,带有 input 可以得到参数page的值
    【解决方案2】:

    你可以添加一个宏:

    if (!Collection::hasMacro('paginate')) {
        Collection::macro('paginate', function ($perPage = 25, $page = null, $options = []) {
            $options['path'] = $options['path'] ?? request()->path();
            $page = $page ?: (Paginator::resolveCurrentPage() ?: 1);
            return new LengthAwarePaginator(
                $this->forPage($page, $perPage)->values(),
                $this->count(),
                $perPage,
                $page,
                $options
            );
        });
    }
    

    然后您可以使用集合对您的项目进行分页:

    collect([1,2,3,4,5,6,7,8,9,10])->paginate(5);
    

    参见Introduction下的扩展收藏

    【讨论】:

      【解决方案3】:

      试试这个:

      $comments = Comment::where('submission_id', $submission->id)
          ->where('parent_id', NULL)
          ->orderBy(DB::raw("count($comment['upvotes']) - count($comment['downvotes'])"), 'desc')
          ->paginate(10);`
      

      SortBy 返回一个 Collection,而您只能在 QueryBuilder 的实例上调用 paginate。 OrderBy 应该返回一个 QueryBuilder 的实例,并且您应该能够使用 DB::raw 语句进行减法。

      ** 编辑

      我刚刚阅读了有关orderByRaw 的信息,这在这种情况下可能很有用:

      $comments = Comment::where('submission_id', $submission->id)
          ->where('parent_id', NULL)
          ->orderByRaw('(upvotes - downvotes) desc')
          ->paginate(10);`
      

      由于我不知道您的 cmets 表的结构,您可能需要对上面的减法进行一些操作。

      几个可能有用的链接:

      【讨论】:

      • 这会返回:语法错误,意外''。但是我用单引号切换了双引号,用双引号切换了单引号,它返回了一个不同的错误。我将对主要帖子进行编辑。
      • @FelixMaxime 你过得怎么样?当您使用单引号时,它将无法将变量的值传递到您的 SQL 语句中,因此它无法理解您所说的 $comment 是什么意思,因为它被视为字符串而不是变量。显然有一个名为 orderByRaw 的函数,您可以使用它,现在将更新我的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-03
      • 2019-04-14
      • 1970-01-01
      • 1970-01-01
      • 2013-02-20
      • 1970-01-01
      相关资源
      最近更新 更多