Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

lukeboy_2002's avatar

Scoretable per user

Hi,

After a long search and some chatgpt I created the following code for a scoring system in livewire.

public function render()
    {
        // Retrieve paginated users with their scores
        $scoreList = DB::table('users')
            ->select(
                'users.username', 'users.image',
                DB::raw('COALESCE(SUM(points.points), 0) AS total_points'),
                DB::raw('COALESCE(SUM(CASE WHEN games.winner_id = users.id THEN 1 ELSE 0 END), 0) AS total_wins'),
                DB::raw('COALESCE(SUM(CASE WHEN games.cup_winner_id = users.id THEN 1 ELSE 0 END), 0) AS total_cups'),
                DB::raw('COUNT(game_user.game_id) AS total_games_played')
            )
            ->leftJoin('game_user', 'game_user.user_id', '=', 'users.id')
            ->leftJoin('games', 'game_user.game_id', '=', 'games.id')
            ->leftJoin('points', function ($join) {
                $join->on('points.user_id', '=', 'users.id')
                    ->on('points.game_id', '=', 'games.id');
            })
            ->whereIn('users.id', User::role('member')->pluck('id'))
            ->groupBy('users.id')
            ->simplePaginate(1); // Adjust the number of items per page as needed

        return view('livewire.team', [
            'scoreList' => $scoreList,
        ]);
    }

here a my migrations

and this is my Liverwire component file

It works fine but something tells me that this code can be easier.

0 likes
1 reply
LaryAI's avatar
Level 58

Your current implementation is functional, but there are a few areas where you can simplify or optimize the code. Here are some suggestions:

  1. Use Eloquent Relationships: Instead of using raw queries, leverage Eloquent relationships to make your code more readable and maintainable.

  2. Eager Loading: Use eager loading to reduce the number of queries executed.

  3. Refactor the Query: You can refactor the query to make it more concise.

Here's a refactored version using Eloquent:

Models

First, ensure your models have the necessary relationships defined.

User.php

class User extends Model
{
    public function games()
    {
        return $this->belongsToMany(Game::class)->withTimestamps();
    }

    public function points()
    {
        return $this->hasMany(Point::class);
    }
}

Game.php

class Game extends Model
{
    public function users()
    {
        return $this->belongsToMany(User::class)->withTimestamps();
    }
}

Point.php

class Point extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function game()
    {
        return $this->belongsTo(Game::class);
    }
}

Livewire Component

Now, refactor your Livewire component to use Eloquent:

public function render()
{
    $scoreList = User::with(['games', 'points'])
        ->whereHas('roles', function ($query) {
            $query->where('name', 'member');
        })
        ->get()
        ->map(function ($user) {
            $totalPoints = $user->points->sum('points');
            $totalWins = $user->games->where('winner_id', $user->id)->count();
            $totalCups = $user->games->where('cup_winner_id', $user->id)->count();
            $totalGamesPlayed = $user->games->count();

            return (object) [
                'username' => $user->username,
                'image' => $user->image,
                'total_points' => $totalPoints,
                'total_wins' => $totalWins,
                'total_cups' => $totalCups,
                'total_games_played' => $totalGamesPlayed,
            ];
        });

    return view('livewire.team', [
        'scoreList' => $scoreList,
    ]);
}

Blade Template

Your Blade template can remain largely the same, as it is already well-structured. Just ensure it matches the data structure returned by the refactored code.

This refactoring leverages Eloquent's relationships and collection methods to make the code more readable and maintainable. It also reduces the complexity of the query logic by using Eloquent's built-in methods.

Please or to participate in this conversation.