---
title: "Query scopes — Advertisements for Laravel | Roundly"
description: "Chain published, active, scheduled, expired, draft, archived, author, placement, category and geo scopes — or start from the facade."
url: https://roundly-consulting.com/open-source/docs/advertisements-for-laravel/query-scopes
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Advertisements for Laravel](https://roundly-consulting.com/open-source/docs/advertisements-for-laravel.md)

# Query scopes

Expressive scopes answer the common questions without hand-written where clauses:

```php
use RoundlyConsulting\Advertisements\Facades\Advertisements;
use RoundlyConsulting\Advertisements\Models\Advertisement;

Advertisement::query()->published()->get();  // published_at reached, not archived
Advertisement::query()->active()->get();      // published AND not expired
Advertisement::query()->scheduled()->get();   // published_at in the future
Advertisement::query()->expired()->get();     // expires_at passed
Advertisement::query()->draft()->get();       // never published
Advertisement::query()->archived()->get();    // explicitly archived
Advertisement::query()->forAuthor($user)->get();

// The facade exposes a fresh builder for chaining:
Advertisements::query()->active()->get();
```

## Every scope

| Scope | Matches |
| --- | --- |
| `published()` | published\_at reached, not archived — includes ads past expires\_at. |
| `active()` | Published and not expired — what you serve. |
| `scheduled()` | published\_at in the future, not archived. |
| `expired()` | expires\_at passed, not archived. |
| `draft()` | Never published (no published\_at), not archived. |
| `archived()` | Explicitly archived. |
| `forAuthor($model)` | Owned by the given polymorphic author. |
| `forPlacement($placement)` | Attached to a placement — model, id or slug. |
| `inCategory($category, $includeDescendants = false)` | In a category — model, id or slug — optionally with nested ones. |
| `targetedAt($viewer)` | Served to a viewer’s location (see Geo-targeting). |
| `whereSlug($slug, locale: null)` | By slug, from sluggable-for-laravel. |

## Composing

Scopes compose with each other and with plain Eloquent:

```php
Advertisement::query()
    ->active()
    ->forPlacement('sidebar')
    ->inCategory('vehicles', includeDescendants: true)
    ->forAuthor($user)
    ->latest('published_at')
    ->paginate(20);
```

Advertisements::query() returns a fresh builder for the configured model (see Custom models); Advertisements::active() is query()->active(), and Advertisements::in($placement) adds forPlacement() on top.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/advertisements-for-laravel.md)
