PHPackages                             laragear/capstone - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. laragear/capstone

ActiveLibrary[Database &amp; ORM](/categories/database)

laragear/capstone
=================

Limit the number of model records by amount or date.

v2.0.0(2mo ago)21MITPHPPHP ^8.3CI passing

Since Apr 8Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/Laragear/Capstone)[ Packagist](https://packagist.org/packages/laragear/capstone)[ Fund](https://github.com/sponsors/DarkGhostHunter)[ Fund](https://paypal.me/darkghosthunter)[ RSS](/packages/laragear-capstone/feed)WikiDiscussions 2.x Synced 1mo ago

READMEChangelog (2)Dependencies (6)Versions (4)Used By (0)

Capstone
========

[](#capstone)

[![Latest Version on Packagist](https://camo.githubusercontent.com/1f55ba8039c4a4255b7a95eb319d6e7a6b1ff40230f7f0529ac9492184c18d33/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6c617261676561722f63617073746f6e652e737667)](https://packagist.org/packages/laragear/capstone)[![Latest stable test run](https://github.com/Laragear/Capstone/actions/workflows/php.yml/badge.svg)](https://github.com/Laragear/Capstone/actions/workflows/php.yml)[![Codecov Coverage](https://camo.githubusercontent.com/7cb1622b6dfb374cdc8b5818e9a0dc03e4ca7ead0d0571129c8ff08d72fc1f3f/68747470733a2f2f636f6465636f762e696f2f67682f4c617261676561722f43617073746f6e652f67726170682f62616467652e7376673f746f6b656e3d4339436336584f785845)](https://codecov.io/gh/Laragear/Capstone)[![Maintainability](https://camo.githubusercontent.com/506c8cbaf4d0452af162bf906f7aa96dcf58670796f4a895d6e917f1f359329a/68747470733a2f2f716c74792e73682f6261646765732f34326337303764372d636532652d343732362d613162652d3239656131353164653731312f6d61696e7461696e6162696c6974792e737667)](https://qlty.sh/gh/Laragear/projects/Capstone)[![Sonarcloud Status](https://camo.githubusercontent.com/4765f66b0297c04e1c871664f61627565c297f06414d7729a9fd94d37b0c7913/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d4c617261676561725f43617073746f6e65266d65747269633d616c6572745f737461747573)](https://sonarcloud.io/dashboard?id=Laragear_Capstone)[![Laravel Octane Compatibility](https://camo.githubusercontent.com/70359a356da237cd29561bc5d0bb80baae775b5ff62f288ed324755382858342/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2532304f6374616e652d436f6d70617469626c652d737563636573733f7374796c653d666c6174266c6f676f3d6c61726176656c)](https://laravel.com/docs/12.x/octane#introduction)

Limit the number of model records by amount or date.

```
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Laragear\Capstone\HasCap;
use Laragear\Capstone\Keep;

class Draft extends Model
{
    use HasCap;

    /**
     * Limits the model records in the table.
     */
    public function keep(Keep $keep)
    {
        $keep->same('post_id')->by(10);
    }
}
```

Become a sponsor
----------------

[](#become-a-sponsor)

[![](.github/assets/support.png)](https://github.com/sponsors/DarkGhostHunter)

Your support allows me to keep this package free, up-to-date and maintainable.

Requirements
------------

[](#requirements)

- PHP 8.3
- Laravel 12 or later

Installation
------------

[](#installation)

You can install the package via Composer.

```
composer require laragear/capstone
```

How this works?
---------------

[](#how-this-works)

This library can limit how many models can be persisted in a table. The only requisite is a primary key, and that these models share a particular column value.

For example, imagine a `Post` model having `Drafts`. To limit the amount of drafts present in the database for that post, this library does it automatically using the `Laragear\Capstone\HasCap` trait. By default, it uses a limit of 5. It only requires a column to group the drafts to keep, which would be `post_id`.

Set up
------

[](#set-up)

Find the Eloquent Model you want to limit, add the `Laragear\Capstone\HasCap` trait with the `keep()` method.

```
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Laragear\Capstone\HasCap;
use Laragear\Capstone\Keep;

class Draft extends Model
{
    use HasCap;

    public function keep(Keep $keep)
    {
       //
    }
}
```

The next step is to configure which column to group the models to keep, otherwise the whole table would be affected. The `keep()` method receives a `Laragear\Capstone\Keep` instance you can use to point out the column (or columns) to group the models.

For example, we can use the `post_id` to group the drafts for a particular post with the `same()` method and the name of the column, which will exclude drafts with different `post_id` from the operation.

```
use Laragear\Capstone\Keep;

public function keep(Keep $keep)
{
    $keep->same('post_id');
}
```

You may also set more than one column to match more records in the database.

```
use Laragear\Capstone\Keep;

public function keep(Keep $keep)
{
    $keep->same('post_id', 'user_id');
}
```

Alternatively, you may use a callback that modifies the query to group the records to limit. The callback receives the `Illuminate\Database\Eloquent\Builder` instance you can adjust to your liking.

```
use Laragear\Capstone\Keep;
use Illuminate\Contracts\Database\Eloquent\Builder

public function keep(Keep $keep)
{
    $keep->same(function (Builder $query) {
        $query
            ->where('post_id', $this->post_id)
            ->whereRelation('post.user', 'is_vip', false)
    });
}
```

Important

The query is using only to group the records that will be kept or deleted, not to [apply limits](#amount-limit).

### Amount limit

[](#amount-limit)

By default, the records are limited by 5. Each time a new record is inserted into the database, the oldest ([by their primary key](#ordering)) is deleted. You may change the amount using the `by()` method.

```
use Laragear\Capstone\Keep;

public function keep(Keep $keep)
{
    $keep->same('post_id')->by(10);
}
```

You also disable the limit by setting it to `0` (zero) or using `all()`. In that case, you should complement this with a [time limit](#time-limit).

```
$keep->same('post_id')->all()->after('-14 days');
```

Tip

You can combine both `by()` and [`after()`](#time-limit) to limit records by amount and time, respectively.

### Time limit

[](#time-limit)

You can also limit the records to keep by a relative date in the past using the `after()` method, which accepts a `DateTimeInterface` like a `Carbon` instance or a string to be parsed through [`strtotime`](https://www.php.net/manual/en/function.strtotime.php).

```
use Laragear\Capstone\Keep;

public function keep(Keep $keep)
{
    $keep->same('post_id')->after('-14 days');
}
```

By default, it uses the model creation timestamp to pick which records should be kept. You may use a different column by setting its name a second parameter.

```
$keep->same('post_id')->after(now()->subMonth(), 'updated_at');
```

Tip

You can combine both [`by()`](#amount-limit) and `after()` to limit records by amount and time, respectively.

### Ordering

[](#ordering)

When the models to keep are queried to exclude them from the deletion, these are ordered by their primary key in descending order. If your models have unordered primary keys, like UUID v4, or strings, you may change the query order by their creation timestamp using `latest()` and `oldest()`.

```
use Laragear\Capstone\Keep;

public function keep(Keep $keep)
{
    $keep->same('post_id')->oldest();
}
```

Both methods also accept the column to sort the records if these don't have a creation timestamp, or you need to sort them using another column.

```
$cap->same('post_id')->latest('saved_at');

$cap->same('post_id')->oldest('published_at');
```

### Force delete

[](#force-delete)

Records that are not kept will be removed using the [`delete()` query method](https://laravel.com/docs/12.x/eloquent#deleting-models-using-queries). If your model uses [soft deletes](https://laravel.com/docs/12.x/eloquent#soft-deleting), you may remove it completely from the databases using `forceDelete()` method.

```
use Laragear\Capstone\Keep;

public function keep(Keep $keep)
{
    $keep->same('post_id')->forceDelete();
}
```

In case you require to issue a condition for force deletion, you can use a variable that evaluates to *true* or *false*, or a callback that receives the model and returns the result of the condition.

```
$keep->same('post_id')->forceDelete(fn ($draft) => $draft->author->isNotVip());
```

### Cancelling deletion

[](#cancelling-deletion)

If you require to disable deleting out-of-bounds records, then you can use `deleteWhen()` and `deleteUnless()` with a condition or callback that evaluates to *truthy* or *falsy*, respectively, as long it's not `null`.

```
use Laragear\Capstone\Keep;

public function keep(Keep $keep)
{
    $keep->same('post_id')->deleteWhen($this->isVip());
}
```

Laravel Octane compatibility
----------------------------

[](#laravel-octane-compatibility)

- There are no singletons using a stale app instance.
- There are no singletons using a stale config instance.
- There are no singletons using a stale request instance.
- There are no static properties written during a request.

There should be no problems using this package with Laravel Octane.

Security
--------

[](#security)

If you discover any security-related issues, issue a [Security Advisor](https://github.com/Laragear/Capstone/security/advisories/new)

License
=======

[](#license)

This specific package version is licensed under the terms of the [MIT License](LICENSE.md), at the time of publishing.

[Laravel](https://laravel.com) is a Trademark of [Taylor Otwell](https://github.com/TaylorOtwell/). Copyright © 2011–2026 Laravel LLC.

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance86

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~110 days

Total

4

Last Release

74d ago

Major Versions

1.x-dev → 2.x-dev2026-03-05

PHP version history (2 changes)v1.0.0PHP ^8.2

2.x-devPHP ^8.3

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/5141911?v=4)[Italo](/maintainers/DarkGhostHunter)[@DarkGhostHunter](https://github.com/DarkGhostHunter)

---

Top Contributors

[![DarkGhostHunter](https://avatars.githubusercontent.com/u/5141911?v=4)](https://github.com/DarkGhostHunter "DarkGhostHunter (5 commits)")

### Embed Badge

![Health badge](/badges/laragear-capstone/health.svg)

```
[![Health](https://phpackages.com/badges/laragear-capstone/health.svg)](https://phpackages.com/packages/laragear-capstone)
```

###  Alternatives

[cybercog/laravel-love

Make Laravel Eloquent models reactable with any type of emotions in a minutes!

1.2k302.7k1](/packages/cybercog-laravel-love)[cviebrock/eloquent-taggable

Easy ability to tag your Eloquent models in Laravel.

567694.8k3](/packages/cviebrock-eloquent-taggable)[clickbar/laravel-magellan

This package provides functionality for working with the postgis extension in Laravel.

423715.4k1](/packages/clickbar-laravel-magellan)[genealabs/laravel-pivot-events

This package introduces new eloquent events for sync(), attach(), detach() or updateExistingPivot() methods on BelongsToMany relation.

1404.9M8](/packages/genealabs-laravel-pivot-events)[reedware/laravel-relation-joins

Adds the ability to join on a relationship by name.

2121.2M13](/packages/reedware-laravel-relation-joins)[aglipanci/laravel-eloquent-case

Adds CASE statement support to Laravel Query Builder.

115157.2k](/packages/aglipanci-laravel-eloquent-case)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
