Skip to content

Instantly share code, notes, and snippets.

@lkmadushan
Last active February 19, 2018 06:43
Show Gist options
  • Save lkmadushan/22b9a60921029d9abf67e6e1cf3965bb to your computer and use it in GitHub Desktop.
Save lkmadushan/22b9a60921029d9abf67e6e1cf3965bb to your computer and use it in GitHub Desktop.
Advance eloquent eager load

Advance Eloquent

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();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment