---
title: "Placements — Advertisements for Laravel | Roundly"
description: "Model ad zones such as a sidebar or in-feed slot, attach ads by model, id or slug, and fetch the active or a random ad for a zone in one call."
url: https://roundly-consulting.com/open-source/docs/advertisements-for-laravel/placements
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)

# Placements

A placement is a zone where ads render — sidebar, header, in-feed. It has a translatable name, a code-facing slug and optional width and height in pixels, which size the creative’s display variant and the text-ad fallback:

```php
use RoundlyConsulting\Advertisements\Models\Placement;

$sidebar = Placement::query()->create([
    'name' => ['en' => 'Sidebar', 'sk' => 'Bočný panel'],
    'slug' => 'sidebar',   // optional — generated from the fallback-locale name when empty
    'width' => 300,        // optional pixel size for the display variant and the text ad
    'height' => 250,
]);

$leaderboard = Placement::query()->create(['name' => ['en' => 'Leaderboard'], 'width' => 728, 'height' => 90]);
$leaderboard->slug;        // "leaderboard"
```

Leave slug empty and it’s generated from the fallback-locale name (Side Banner → side-banner, suffixed -2 when taken). A slug you supply is kept byte-for-byte, a taken one throws SlugAlreadyTakenException, and it never changes afterwards — it’s the storage key of the placement’s creatives (creative:{slug}), so a rename must not orphan them.

## Assigning and serving

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

Advertisements::for($ad)->placements()->attach(['sidebar', $leaderboard->id]); // models, ids, or slugs
Advertisements::for($ad)->placements()->sync(['sidebar']);
Advertisements::for($ad)->placements()->detach(['sidebar']);
Advertisements::for($ad)->runsIn('sidebar'); // true

// Active ads in a placement, or one at random:
Advertisements::in('sidebar')->get();
Advertisements::random('sidebar');

Advertisement::query()->forPlacement($sidebar)->get(); // model, id, or slug
```

- for($ad)->placements() — attach() adds without detaching existing ones, sync() replaces the set, detach() removes. Each returns the ad with placements reloaded.
- Every method accepts placement models, ids or slugs. A string is matched as a slug first; a digit-only string no placement uses as its slug is then taken as an id, so form and route input ('12') works as-is. An unknown reference is skipped by attach(), sync() and detach() and matches nothing in in() or forPlacement().
- for($ad)->runsIn($placement) tells whether the ad is attached.
- in($placement) is active()->forPlacement($placement); random() picks one active ad at random, optionally per placement, or returns null.
- targetedIn($placement, $viewer) is the geo-aware version of in() — see Geo-targeting.

## Relations

```php
$ad->placements;            // BelongsToMany<Placement> — the pivot carries meta + timestamps
$sidebar->advertisements;   // BelongsToMany<Advertisement>
$sidebar->width;            // ?int
$sidebar->height;           // ?int
```

The advertisement\_placement pivot is unique per pair; its foreign keys cascade when an ad or placement row is permanently removed. Placements use soft deletes.

## 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)
