ソート方法はこちらにも記載してるやつ
ランキング一覧
- web/routes.php
// ...省略
// ランキング一覧
Route::get('/ranking', [RankingController::class, 'index'])->name('ranking.index');
- App/Controllers/RankingController.php
<?php
namespace App\Http\Controllers;
use App\Models\User;
class RankingController extends Controller
{
public function index()
{
$users = User::query()
->withCount([
'posts AS total_view_count' => function ($query) {
$query->select(DB::raw("SUM(view_count) as view_count_sum"));
}
])->orderBy('total_view_count', 'desc')
->get();
return view('ranking.index', compact('users'));
}
}
- resources/views/ranking/index.blade.php
@foreach ($users as $index => $user)
<div>ランキング: {{ $index + 1 }}位</div>
<div>{{ $user->name }}</div>
@endforeach
ソート部分に関して
$users = User::query()
->withCount([
'posts AS total_view_count' => function ($query) {
$query->select(DB::raw("SUM(view_count) as view_count_sum"));
}
])->orderBy('total_view_count', 'desc')
->get();
withCount
でリレーション先のposts
のカウントを取得する
ただ何も指定しないと、posts
の合計数になってしまうので、
function内のselect(DB::raw("SUM(view_count)...
にて閲覧数の合計をtotal_view_count
として取得するようにカスタマイズしてる
あとはorderByでそのtotal_view_count
を指定してあげればOK
ユーザーIDを元にその人のランク数を取得する
詳細画面などでその人のランクを表示したい場合
- App/Controllers/RankingController.php
<?php
namespace App\Http\Controllers;
use App\Models\User;
class RankingController extends Controller
{
public function show(User $user)
{
$users = User::query()
->withCount([
'posts AS total_view_count' => function ($query) {
$query->select(DB::raw("SUM(view_count) as view_count_sum"));
}
])->orderBy('total_view_count', 'desc')
->get();
$rank = array_search($user_id, $users->pluck('id')->toArray()) + 1;
return view('ranking.show', compact('user', 'rank'));
}
}
$users
にはCollectionが入っているのでpluck('id')->toArray()
でIDのみの配列にし、array_search
でindex検索してる
あとはview側で {{ $rank }}位のように表示すればOK
例えばユーザー (
users
) がブログ (posts
) を投稿できるポータルサイトがあるとするその際にユーザーのブログの閲覧数でランキングを作る方法