---
title: "Categories — Advertisements for Laravel | Roundly"
description: "Organise ads into a nestable category tree and filter by one category alone or together with every category nested beneath it."
url: https://roundly-consulting.com/open-source/docs/advertisements-for-laravel/categories
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)

# Categories

Categories form a nestable tree with a translatable name and a code-facing slug:

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

$vehicles = Category::query()->create(['name' => ['en' => 'Vehicles', 'sk' => 'Vozidlá']]); // slug "vehicles"
$bikes = Category::query()->create(['name' => ['en' => 'Bikes'], 'parent_id' => $vehicles->id]);

$ad->category;              // BelongsTo<Category>
$bikes->parent;             // ?Category
$vehicles->children;        // HasMany<Category>
$vehicles->descendants();   // every nested category
$vehicles->advertisements;  // HasMany<Advertisement>

Advertisement::query()->inCategory($vehicles)->get();                            // direct only
Advertisement::query()->inCategory('vehicles', includeDescendants: true)->get(); // + nested
```

inCategory() accepts a model, id, slug or numeric-string id — a string is matched as a slug first, a digit-only one no category uses as its slug is then taken as an id. An unknown reference matches nothing rather than every uncategorised ad. descendants() walks the tree recursively.

AdvertisementData’s category argument accepts the same model, id or slug and resolves it to category\_id — categories are never created implicitly.

## Category slugs

Category slugs behave like placement slugs: generated from the fallback-locale name when empty, kept byte-for-byte when supplied (SlugAlreadyTakenException when taken) and never changed afterwards. Categories use soft deletes; when a category row is permanently removed, its children’s parent\_id and its ads’ category\_id become null.

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