Avoid repeating yourself with Laravel Model Scopes

Photo by Brett Jordan on Unsplash

Setup

Imagine you have models for Blog and Post and a relationship between the two — Blog hasMany Post.

Problem

Across your site, you need to show the 3 most recently-published posts for each blog. Eloquent makes this easy:

$blog->posts->sortByDesc('published_at')->take(3)

Writing a model scope

On your Post model, add the following function:

public function scopeRecent($query)
{
return $query->orderByDesc('published_at')->limit(3);
}
$blog->posts()->recent()->get()
public function scopeRecent($query, $count)
{
return $query->orderByDesc('published_at')->limit($count);
}

Some extra notes

Why is it sometimes orderBy and sometimes sortBy?

Inside the scope, you are querying the data as it gets fetched from the database — so you need to use Eloquent functions.

Telling your editor/IDE about magic methods

Because your scope is a magic method, your editor won’t be aware of the property it enables so you won’t get autocomplete or any of the other benefits your IDE should bring.

/*
* @method mixed recent() Fetches recent items
*/

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store