首页 > 解决方案 > 为集合分页,Laravel

问题描述

我尝试从 foreach 向每个用户添加一些新值,但是因为我使用 get,所以现在我不能在响应时使用分页,但我还需要向每个用户添加这些值。有任何想法吗?

public function statistics()
    {
        $users = User::select(['id', 'name'])->get();
        foreach ($users as $key => $user) {
            $history = AnswerHistory::where('user_id', '=', $user->id)->get();
            $user->total_votes = count($history);
            $user->total_time = gmdate("H:i:s", ($history->sum('answer_time')));
        }

        return response()->json($users);
    }

标签: laravellaravel-7

解决方案


默认情况下,你想要的东西在 laravel 中是不可能的,但是你可以做一些事情。

解决方案一,您可以先返回分页器,然后修改集合。

    $users = User::select(['id', 'name'])->paginate(4)->toArray();

    $users['data'] = array_map(function ($user) {
            $history = AnswerHistory::where('user_id', '=', $user->id)->get();
            $user->total_votes = count($history);
            $user->total_time = gmdate("H:i:s", ($history->sum('answer_time')));
        return $user;
    }, $users['data']);

    return  $users;

解决方案二宏观方式。如果您愿意,请将 Collection 宏添加到服务提供者。这样您就可以在任何集合上调用 paginate():请参阅 AppServiceProvider.php 以获取示例实现。

    public function boot()
    {
        Collection::macro('paginate', function ($perPage, $total = null, $page = null, $pageName = 'page') {
            $page = $page ?: LengthAwarePaginator::resolveCurrentPage($pageName);

            return new LengthAwarePaginator(
                $this->forPage($page, $perPage),
                $total ?: $this->count(),
                $perPage,
                $page,
                [
                    'path' => LengthAwarePaginator::resolveCurrentPath(),
                    'pageName' => $pageName,
                ]
            );
        });
    }

然后你的代码将是这样的

        $users = User::select(['id', 'name'])->get();
        foreach ($users as $key => $user) {
            $history = AnswerHistory::where('user_id', '=', $user->id)->get();
            $user->total_votes = count($history);
            $user->total_time = gmdate("H:i:s", ($history->sum('answer_time')));
        }

        return response()->json($users->paginate(4));

解决方案三子类方式。如果您想要一个不同于标准的“可分页”集合,Illuminate\Support\Collection实现一个副本,Collection.php并简单地将您use Illuminate\Support\Collection的依赖文件顶部的语句use App\Support\Collection

<?php

namespace App\Support;

use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection as BaseCollection;

class Collection extends BaseCollection
{
    public function paginate($perPage, $total = null, $page = null, $pageName = 'page')
    {
        $page = $page ?: LengthAwarePaginator::resolveCurrentPage($pageName);

        return new LengthAwarePaginator(
            $this->forPage($page, $perPage),
            $total ?: $this->count(),
            $perPage,
            $page,
            [
                'path' => LengthAwarePaginator::resolveCurrentPath(),
                'pageName' => $pageName,
            ]
        );
    }
}

你的代码会是这样的

// use Illuminate\Support\Collection
use App\Support\Collection;

        $users = User::select(['id', 'name'])->get();
        foreach ($users as $key => $user) {
            $history = AnswerHistory::where('user_id', '=', $user->id)->get();
            $user->total_votes = count($history);
            $user->total_time = gmdate("H:i:s", ($history->sum('answer_time')));
        }

        return response()->json((new Collection($users))->paginate(4);

推荐阅读