Imagine you have two models call User and Activity. The relationship between them is,
User hasMany Activity
If you want to fetch users with their last activity you often need to eager load users with their activities and grab the last one of activities. The trade off that is you are eager loading unwanted activity models and it will be a performance issue when your database grows. Following is a simple trick that you come up with eager loading the last activity of the user.
class User extends Model
{
public function activities()
{
return $this->hasMany(Activity::class);
}
public function lastActivity()
{
return $this->hasOne(Activity::class, 'id', 'last_activity_id');
}
public function scopeWithLastActivity($query)
{
$lastActivityQuery = Activity::select('id')
->whereRaw('user_id = users.id')
->latest()
->limit(1)
->getQuery();
$query->select('users.*')
->selectSub($lastActivityQuery, 'last_activity_id')
->with('lastActivity');
}
}
Now you use above scope query to fetch users with their eager loaded last activity.
User::withLastActivity()->get();