简体   繁体   中英

Laravel get a model collection ordered by a relation column

I'm trying to obtain a ranking table based on how much points that has an User.

My User model is (simplified):

namespace Gamify;
class User extends Model
{
    protected $table = 'users';

    public function points()
    {
        return $this->hasMany('Gamify\Point');
     }

     public function scopeMember($query)
     {
         return $query->where('role', '=', 'default');
     }
 }

And Point model is:

namespace Gamify;
class Point extends Model
{
    protected $table = 'points';

    protected $fillable = array(
        'points',
        'description'
    );

    public function user()
    {
        return $this->belongsTo('Gamify\User');
    }
}

I'd like to obtain a Collection of users with the sum of its points, ordered by this sum.

Something like this ( this code is only a mockup ):

public static function getRanking($limitTopUsers = 10)
{
    return User::member()->orderBy(sum('points'))->get();
}

I've been playing with User::with() and scopes and I'm trying not to use DB::raw() .

Can anyone help me? Thanks in advance.

Try

public function points ()
    {
        return $this->hasMany('Gamify\Point')
            ->selectRaw('sum(points) as sum, user_id')
            ->groupBy('user_id');
    }

and use it like

        $data = User::with('points')->get();

Based on @nextt1's code, this is my final approach:

On User's Model:

public function points()
{
    return $this->hasMany('Gamify\Point')
        ->selectRaw('sum(points) as sum, user_id')
        ->groupBy('user_id');
}

public function getExperiencePoints()
{
    return $this->points()->sum('points');
}

And then I've created a function in order to call the ranking:

public static function getRanking($limitTopUsers = 10)
{
    $users = User::Member()->with('points')->get();

    $users = $users->sortByDesc(function ($user) {
        return $user->getExperiencePoints();
    })->take($limitTopUsers);

    return $users;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM