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.