为一个集合分页,拉拉威尔



我试图从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);
}

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

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

$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;

解决方案二宏方式。如果愿意,请将"集合"宏添加到"服务提供程序"中。这样,您就可以对任何集合调用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));

解决方案三子类方式。如果您想要一个不同于标准IlluminateSupportCollection的"可分页"集合,请在应用程序中实现Collection.php的副本,并简单地将依赖文件顶部的use IlluminateSupportCollection语句替换为use AppSupportCollection:

<?php
namespace AppSupport;
use IlluminatePaginationLengthAwarePaginator;
use IlluminateSupportCollection 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 IlluminateSupportCollection
use AppSupportCollection;
$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);

根据您的帖子,User有许多AnswerHistory。你可以在他们之间建立关系。

所以用withCount:得到total_votestotal_time

$users = User::withCount('answerHistories AS total_votes')
->withCount(['answerHistories AS total_time' => function($query) {
$query->select(DB::raw("SUM(answer_time)"));
}])->paginate(10);

您可以通过getCollection获取分页数据,并在中更改数据

$users->getCollection()->transform(function ($data) {
$data->total_time = gmdate('H:i:s', $data->total_time);
return $data;
});

您可以自己创建分页,看看这个Laravel文档https://laravel.com/docs/7.x/pagination#manually-创建一个分页器。我建议使用LengthAwarePaginator下面是一些数组的代码示例

// creating pagination
$offset = max(0, ($page - 1) * $perPage);
$resultArray = array_slice($result, $offset, $perPage);
$paginator = new LengthAwarePaginator($resultArray, count($result), $perPage, $page);
$paginator->setPath(url()->current());
$paginator->appends(['per_page' => $perPage]);
return response()->json([
'message' => 'Success',
'data'    => $paginator
]);

但我认为你的案例有更好的"好"解决方案,你可以用hasManyLaravel关系和with函数加载AnswerHistory

最新更新