---
title: "Custom post model — Posts for Laravel | Roundly"
description: "Extend Post with your own subclass — the package creates, queries and binds it everywhere, and Posts::query() returns it."
url: https://roundly-consulting.com/open-source/docs/posts-for-laravel/custom-model
language: en
---

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

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

# Custom post model

Post is deliberately not final. Subclass it and point posts.model at your class:

```php
namespace App\Models;

use RoundlyConsulting\Posts\Models\Post;

class Article extends Post
{
    // your relations, scopes, accessors and overrides
}
```

```php
// config/posts.php
'model' => App\Models\Article::class,
```

The package resolves posts.model everywhere — in create(), publishDue() and the scheduled-publish command, the listeners, route binding, HasPosts, the category and tag posts() relations and the post factory — so your subclass is what gets created, queried and bound. In host code, reach it through the facade:

```php
use RoundlyConsulting\Posts\Facades\Posts;

Posts::query();                    // Builder over the configured model (Article)
Posts::published();                // its published() scope
Posts::findBySlug('hello-world');  // ?Article
Posts::create($data);              // creates an Article
```

Absent or blank config resolves Post; any other value must be Post or a subclass of it, or the toolkit’s InvalidConfigurationException is thrown naming the key — a foreign class is never silently replaced. Post::findBySlug() always uses the packaged class — use Posts::findBySlug() or Posts::query() instead. Category and Tag are final.

## Other extension points

- Tables — rename any table under posts.tables.\* before migrating.
- Keys — key\_type and primary\_key\_type before migrating.
- SEO and JSON-LD — the seo.\* and json-ld.\* defaults, setSeo() per post, and the published posts-views.
- Workflow hooks — listen to the four lifecycle events.
- Media — bucket names, disk, widths, the og:image variant and inline behaviour under posts.media.\*.
- Moderation — posts.moderation.\*, or listen to the reports events yourself.

## 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/posts-for-laravel.md)
