PHPackages                             xetaio/xetaravel-counts - 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. xetaio/xetaravel-counts

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

xetaio/xetaravel-counts
=======================

Automatic \*\_count for Laravel belongsTo and belongsToMany relations.

2.0.0(5mo ago)0792MITPHPPHP ^8.2CI passing

Since Nov 17Pushed 5mo agoCompare

[ Source](https://github.com/XetaIO/Xetaravel-Counts)[ Packagist](https://packagist.org/packages/xetaio/xetaravel-counts)[ Docs](https://github.com/XetaIO/Xetaravel-Counts)[ RSS](/packages/xetaio-xetaravel-counts/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (5)Versions (3)Used By (0)

Xetaravel Counts
================

[](#xetaravel-counts)

> Unit TestsStable VersionDownloadsLaravelLicense[![GitHub Workflow Status](https://camo.githubusercontent.com/be5afd580adb4e1fbfac1f38e97deff366f8d94ccd30597c85220ac98edfa7f3/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f58657461494f2f58657461726176656c2d436f756e74732f74657374732e796d6c3f7374796c653d666c61742d737175617265)](https://github.com/XetaIO/Xetaravel-Counts/actions/workflows/tests.yml)[![Latest Stable Version](https://camo.githubusercontent.com/9ed77ccf3d94bbcd393e106efe7491c512df98dea45a66bbfa421671df1d2ab6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f58657461494f2f58657461726176656c2d436f756e74732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/xetaio/xetaravel-counts)[![Total Downloads](https://camo.githubusercontent.com/34934a570636685727a8f268b416c39f436dd5567e23ada9259e6d4953e4b3c6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f78657461696f2f78657461726176656c2d636f756e74732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/xetaio/xetaravel-counts)[![Laravel 12.0](https://camo.githubusercontent.com/9d9aaa85e79f231c19984831c9f0c1db17191b7a8bec6ca844c9659dc1230bb8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d2533453d31322e302d6634363435662e7376673f7374796c653d666c61742d737175617265)](http://laravel.com)[![License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](https://github.com/XetaIO/Xetaravel-Counts/blob/master/LICENSE)

A lightweight Laravel package that automatically maintains `*_count` columns for:

- `belongsTo` relations (ex: Category → Article)
- `belongsToMany` relations via pivot models (ex: Material ↔ Part)

This allows models to keep real-time counters in the database without writing custom observers or manual logic.

Perfect for dashboards, ERPs, statistics, inventory systems, and any domain where counts must remain immediately available and consistent.

---

✨ Features
----------

[](#-features)

- 🔹 Automatic increment/decrement on create/delete
- 🔹 Automatic sync when foreign key changes (update)
- 🔹 Automatic increment on restore (SoftDelete only)
- 🔹 Automatic increment/decrement on attach/detach/sync (pivot)
- 🔹 Zero configuration for Laravel service provider (auto-discovery)
- 🔹 Simple traits you can reuse anywhere
- 🔹 Works on Laravel 12+

---

📦 Installation
--------------

[](#-installation)

Install via Composer:

```
composer require xetaio/xetaravel-counts
```

---

📚 Usage
-------

[](#-usage)

This package provides a trait to use in your Models: `HasCounts` — `belongsTo` &amp; `belongsToMany` relations

### 1️⃣ Example for `belongsTo` relations :

[](#1️⃣-example-for-belongsto-relations-)

Used when a child belongs to a parent, and the parent stores a `*_count`.

You have:

- categories.articles\_count
- articles.category\_id

*Category model*

```
use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    protected $fillable = ['name', 'articles_count'];

    public function articles()
    {
        return $this->hasMany(Article::class);
    }
}
```

*Article model (child)*

```
use Illuminate\Database\Eloquent\Model;
use Xetaio\Counts\Concerns\HasCounts;

class Article extends Model
{
    use HasCounts;

    protected $fillable = ['title', 'category_id'];

    protected static array $countsConfig = [
        'category' => 'articles_count',
    ];

    public function category()
    {
        return $this->belongsTo(Category::class);
    }
}
```

ActionEffectArticle created`category.articles_count++`Article deleted`category.articles_count--`Article restored (SofDeletes only)`category.articles_count++`Article moved to another categorydecrements old, increments new### 2️⃣ Example for `belongsToMany` relations :

[](#2️⃣-example-for-belongstomany-relations-)

Used when two models are linked via a pivot table and both have a `*_count`.

Example:

- `materials.parts_count`
- `parts.materials_count`
- `material_part` pivot table

*Material model*

```
class Material extends Model
{
    protected $fillable = ['name', 'parts_count'];

    public function parts()
    {
        return $this->belongsToMany(Part::class, 'material_part')
            ->using(MaterialPart::class) // We need a Pivot Model
            ->withTimestamps();
    }
}
```

*Part model*

```
class Part extends Model
{
    protected $fillable = ['name', 'materials_count'];

    public function materials()
    {
        return $this->belongsToMany(Material::class, 'material_part')
            ->using(MaterialPart::class) // We need a pivot model
            ->withTimestamps();
    }
}
```

*Pivot model (the key part)*

```
use Illuminate\Database\Eloquent\Relations\Pivot;
use Xetaio\Counts\Concerns\HasCounts;

class MaterialPart extends Pivot // Extends to Pivot
{
    use HasCounts;

    /**
     * Config the counts
     */
    protected static array $countsConfig = [
        'material' => 'parts_count',
        'part' => 'materials_count',
    ];

    public function material()
    {
        return $this->belongsTo(Material::class);
    }

    public function part()
    {
        return $this->belongsTo(Part::class);
    }
}
```

ActionEffect`material->parts()->attach(part)`increments both counts`material->parts()->detach(part)`decrements both counts`sync([...])`decrements/increments both counts\--

⚡ Performance Notes
-------------------

[](#-performance-notes)

This package uses:

`increment()` / `decrement()` → atomic SQL updates

No heavy SELECT COUNT(\*)

No observers per model

No risk of race conditions beyond DB atomic ops

For large-scale systems, this approach is highly performant.

\--

🤝 Contributing
--------------

[](#-contributing)

Pull Requests are welcome! Feel free to suggest improvements, new features, or optimizations.

###  Health Score

38

—

LowBetter than 85% of packages

Maintenance70

Regular maintenance activity

Popularity17

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity48

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 ~9 days

Total

2

Last Release

167d ago

Major Versions

1.0.0 → 2.0.02025-11-27

### Community

Maintainers

![](https://www.gravatar.com/avatar/b411de63e10c9029d2d06da585856f15db12c23395bc908f085fad15638a8098?d=identicon)[Xety](/maintainers/Xety)

---

Top Contributors

[![Xety](https://avatars.githubusercontent.com/u/8210023?v=4)](https://github.com/Xety "Xety (20 commits)")

---

Tags

cachecountcountinglaravellaravel-frameworklaravel-packagemodelrelationslaraveldatabaseeloquentpivotbelongsToManycounts

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/xetaio-xetaravel-counts/health.svg)

```
[![Health](https://phpackages.com/badges/xetaio-xetaravel-counts/health.svg)](https://phpackages.com/packages/xetaio-xetaravel-counts)
```

###  Alternatives

[mongodb/laravel-mongodb

A MongoDB based Eloquent model and Query builder for Laravel

7.1k7.2M71](/packages/mongodb-laravel-mongodb)[spiritix/lada-cache

A Redis based, automated and scalable database caching layer for Laravel

591444.8k2](/packages/spiritix-lada-cache)[pdphilip/elasticsearch

An Elasticsearch implementation of Laravel's Eloquent ORM

145360.2k4](/packages/pdphilip-elasticsearch)[toponepercent/baum

Baum is an implementation of the Nested Set pattern for Eloquent models.

3154.7k](/packages/toponepercent-baum)[czim/laravel-filter

Filter for Laravel Eloquent queries, with support for modular filter building

8973.0k3](/packages/czim-laravel-filter)[eusonlito/laravel-database-cache

Cache Database Query results on Laravel Query Builder or Eloquent

194.2k](/packages/eusonlito-laravel-database-cache)

PHPackages © 2026

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