Skip to content

Instantly share code, notes, and snippets.



Last active Dec 7, 2020
What would you like to do?

~Laravel | Keep Eloquent queries DRY by using Local Scopes

Consider the following example.

// posted withtin 14 days
$recentPosts = Post::where('created_at', '>', now()->subDays(14))

// posted within 30 days
$popularPosts = Post::where('created_at', '>', now()->subDays(30))
  ->orderBy('views_count', 'desc')->take(5)->get();

In the example above we are repeating the same piece of code for both queries, we can extract the common parts of the two queries and encapsulate that somewhere else. The part that stays the same here is the Post::where('created_at', '>', now()->subDays(numberOfDays)) part.

One way to put this common behaviour somewhere else is to use Local Scopes in Laravel. You define the scope on your model.

class Post extends Model
  public function scopePostedWithinDays($query, $days = 14)
    return $query->where('created_at', '>', now()->subDays($days));

And then the previous queries can be refactored to use the new scope.

$recentPosts = Post::postedWithinDays(14)->latest()->take(10)->get();
$popularPosts = Post::postedWithinDays(30)->orderBy('views_count', 'desc')->take(5)->get();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment