Mahamudul Hasan Rubel
HomeAboutProjectsSkillsExperienceBlogPhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • About
  • Projects
  • Skills
  • Experience
  • Blog
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
LaravelPHPJune 21, 20264 min read

Mastering Laravel Eloquent Scopes: Writing Reusable Query Constraints

Mastering Laravel Eloquent scopes allows you to write cleaner database queries by encapsulating complex logic into reusable, readable model methods.

laraveleloquentphpdatabaseclean-coderefactoringTutorial
Minimalist photo of a green notepad and pencil on a white background with a drawn question mark.

Last month, I was debugging a legacy codebase where the same "active user" filter was copy-pasted across six different controllers. Every time the business logic for what defined an "active" user changed, we had to hunt down every instance of where('last_login_at', '>', now()->subDays(30))->where('is_banned', false). It was a nightmare. That’s when I forced a refactor to use Eloquent scopes.

If you’re still writing raw where clauses all over your controllers, you’re missing out on one of the most powerful features in Laravel. Eloquent scopes let you define common query constraints directly on your model, turning messy chains into expressive, readable code.

Understanding Laravel Eloquent Scopes

Think of a scope as a shortcut for your query builder. Instead of repeating logic, you define a method prefixing the word scope in your model. Laravel then allows you to call these methods without the prefix.

Here is the basic structure for a local scope in a User model:

PHP
public function scopeActive($query)
{
    return $query->where('last_login_at', '>', now()->subDays(30))
                 ->where('is_banned', false);
}

Now, instead of that long chain, your controller code looks like this:

PHP
$users = User::active()->get();

It’s cleaner, easier to read, and most importantly, it’s defined in exactly one place. If you're looking for more ways to keep your models tidy, I've written previously about Mastering Laravel Traits for Cleaner Eloquent Models which pairs perfectly with this approach.

Why You Should Use Eloquent Scopes

A close-up of a coin-operated telescope set against a beautiful cloudy sky, ideal for travel imagery.

Early in my career, I ignored scopes because I thought they were "extra work." I was wrong. The real value comes when you need to pass arguments to your queries.

Let's say you want to filter users by their subscription status. You can pass parameters directly into your scope:

PHP
public function scopeOfSubscription($query, $plan)
{
    return $query->where('subscription_plan', $plan);
}

#6A9955">// Usage
$premiumUsers = User::active()->ofSubscription('premium')->get();

By chaining these, you build highly readable queries that read almost like a natural sentence. It’s the closest you’ll get to documentation-as-code.

Avoiding the "Wrong Turn" Trap

We once tried to put all our filtering logic into the Controller itself. We thought it would be "easier" to see everything in one place. That lasted about two days before we realized we couldn't reuse the logic for our API endpoints or console commands.

If you're building out your API layer, ensure you aren't leaking your database schema into your responses; check out Mastering Laravel API Resources: A Guide to Clean JSON Responses to handle that separation properly.

When you move logic into scopes, you also make it easier to write unit tests. You can test the scope in isolation to ensure it returns the correct query builder instance, rather than trying to test your entire controller logic just to verify a where clause.

Global Scopes for Automatic Constraints

Sometimes you have a constraint that should always be applied, like softDeletes or a tenant_id check in a multi-tenant application. That’s where global scopes come in.

Unlike local scopes, global scopes are applied automatically to every query on that model. You define them by creating a class that implements Illuminate\Database\Eloquent\Scope.

PHP
#6A9955">// Inside your model's booted method
protected static function booted()
{
    static::addGlobalScope('published', function ($builder) {
        $builder->where('published_at', '<=', now());
    });
}

Be careful with global scopes. I've seen developers accidentally bury logic that was hard to override later. If you need to "escape" a global scope, you can always use User::withoutGlobalScope('published')->get().

Frequently Asked Questions

Q: Can I use scopes with relationships? A: Absolutely! You can chain scopes directly onto relationships, like User::find(1)->posts()->active()->get(). It works exactly like you’d expect.

Q: Should I put all my query logic in scopes? A: No. Don't over-engineer simple queries. If you're only using a where clause once, keep it in the controller. Use scopes when you find yourself repeating the same logic at least twice.

Q: Is there a performance hit? A: Negligible. You're simply adding a method call to the query builder stack. It’s significantly faster than the maintenance cost of fixing broken queries across your app.

Final Thoughts

Implementing scopes is a rite of passage for moving from a junior to a mid-level Laravel developer. They don't just make your code cleaner; they make your database queries intentional.

I’m still careful not to bloat my models with too many scopes. If a model has 30 different scopes, it’s probably time to split it up or rethink your architecture. Start small, identify the repetition, and refactor one scope at a time. You'll thank yourself during the next on-call rotation.

Back to Blog

Similar Posts

Two street cleaners working in Brasília, Brazil, wearing bright orange uniforms.
LaravelPHPJune 21, 20264 min read

Mastering Laravel Traits for Cleaner Eloquent Models

Master Laravel traits to simplify your Eloquent models. Learn how to implement effective PHP code reuse and follow DRY programming best practices today.

Read more
Three syringes arranged on a red surface showcasing medical equipment with copy space.
LaravelPHPJune 21, 20264 min read

Laravel dependency injection: A Practical Guide to Method Injection

Laravel dependency injection in controller methods simplifies your code. Learn how to use method injection effectively to build cleaner, more testable apps.

Read more
A minimalist photo of a card with 'Big Data' text inside a green envelope, showcasing modern concepts.
LaravelPHPJune 21, 20264 min read

Laravel Database Transactions: A Guide to Data Integrity

Master laravel database transactions to ensure your application remains consistent. Learn how to implement atomic operations and avoid partial data updates.

Read more