Create Reusable Query With Laravel Query Scope
Tags: laravel, eloquentorm, backend, php
Published: 2023-01-12 14:31:39

---
title: Create Reusable Query With Laravel Query Scope
published: true
date: 2022-06-26 09:00:34 UTC
tags: 
- Laravel
- EloquentORM
- Backend
- PHP
canonical_url: https://fajarwz.com/blog/create-reusable-query-with-laravel-query-scope/
---
![Scope illustration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4qyrzmuga1osst9dwjdd.png)

One of the best feature Laravel have is [Laravel Eloquent ORM](https://laravel.com/docs/9.x/eloquent). Using Eloquent ORM is easy and it can makes our query simpler, cleaner than [Query Builder](https://laravel.com/docs/9.x/queries#main-content) but sometimes it can also be so long, and maybe we need to reuse the query too. 

Is it possible to create a reusable query in Laravel Eloquent ORM?

## Laravel Query Scope
We can use query scope to achieve the above situation. Here i will explain about the Laravel Local Scope.

For example if we want to get only the post that is currently marked as non-draft or published, we can use this query:

```php
$publishedPosts = Post::where('is_draft', false)->get();
```

But I need to use this query in some places, not just in a place. And I don't want to write this everytime I need it because it is quite long. Then we need to create a query scope for this.

### Simple Scope
Create a method inside your model and insert above query to it, name the method with `scope` prefix like so

```php
<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class Post extends Model
{
    public function scopePublished($query)
    {
        return $query->where('is_draft', false);
    }
}
```

Now we have created the scope. However, we should not include the scope prefix when calling the method.

```php
use App\Models\Post;
 
$publishedPosts = Post::published()->get();
```

Now it is more readable, shorter, and reusable. Even you can chain calls scopes for example if you have a `popular` scope you can chain it like so

```php
use App\Models\Post;

$popularPublishedPosts = Post::published()->popular()->get();
```

> **Read also:**
> * [Create Global Query With Laravel Global Scope](https://fajarwz.com/blog/create-global-query-with-laravel-global-scope/)
> * [Laravel Rest API Authentication Using JWT Tutorial](https://fajarwz.com/blog/laravel-rest-api-authentication-using-jwt-tutorial/)
</blockquote>

### Dynamic Scope
We can also create a scope that accepts parameters like so

```php
class User extends Model {

    public function scopeActive($query, $value)
    {
        return $query->where('is_active', $value);
    }

}
```

Now we can use the scope dynamically

```php
// Get active users
$activeUsers = User::active(true)->get();

// Get inactive users
$inactiveUsers = User::active(false)->get();
```

## Conclusions
And that's it, we have tried our own local scope. Now we know how to create and run a local scope.

## Further Reading
[Query Scopes - Laravel Docs](https://laravel.com/docs/9.x/eloquent#query-scopes)

## Read Also
[Create Global Query With Laravel Global Scope](https://fajarwz.com/blog/create-global-query-with-laravel-global-scope/)