PHPackages                             kolydart/laravel - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. kolydart/laravel

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

kolydart/laravel
================

A collection of laravel helper classes

1.4(3w ago)1761GPL-3.0-or-laterPHPPHP &gt;=7.4

Since Feb 8Pushed 2w ago1 watchersCompare

[ Source](https://github.com/kolydart/laravel)[ Packagist](https://packagist.org/packages/kolydart/laravel)[ RSS](/packages/kolydart-laravel/feed)WikiDiscussions master Synced today

READMEChangelogDependencies (32)Versions (23)Used By (0)

kolydart/laravel
================

[](#kolydartlaravel)

> **Document Purpose**: Technical documentation for Laravel package providing ordered pivot relationships management tools. Describes installation, usage, and API reference.

A collection of Laravel helper classes including ordered pivot relationships functionality.

> Additional documentation is available in the [`src/docs/`](src/docs/) folder.

Table of Contents
-----------------

[](#table-of-contents)

- [Installation](#installation)
- [Audited Relations](#audited-relations)
- [Ordered Pivot Relationships](#ordered-pivot-relationships)
    - [Quick Start](#quick-start)
    - [Components](#components)
    - [Usage Examples](#usage-examples)
    - [API Reference](#api-reference)
    - [Migration from Manual Implementation](#migration-from-manual-implementation)
- [Additional Components](#additional-components)
- [Testing Helpers](#testing-helpers)
- [Testing](#testing)
- [License](#license)

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

[](#installation)

```
composer require kolydart/laravel
```

The service provider will be automatically registered via Laravel's package auto-discovery.

Audited Relations
-----------------

[](#audited-relations)

The `HasAuditedRelations` trait provides audited variants of `BelongsToMany` pivot operations. Audit entries are written on the **parent** model — never on pivot models — which avoids double-audits and lets you reverse-query from either side of the relation.

### When to use

[](#when-to-use)

Use `HasAuditedRelations` on a parent model when you need to:

- audit `attach` / `detach` / `sync` / `toggle` operations on a relation
- record additional pivot attributes (e.g. `role`)
- reorder a `BelongsToMany` relation **silently** (no phantom audit entries)
- avoid the double-audit problem caused by pivot models using `Auditable`

```
use Kolydart\Laravel\App\Traits\HasAuditedRelations;

class Item extends Model
{
    use HasAuditedRelations;

    public function agents() { return $this->belongsToMany(Agent::class)->withPivot('role', 'order'); }
    public function instruments() { return $this->belongsToMany(Instrument::class)->withPivot('order'); }
}

// In a controller:
$item->auditedSyncRoledPivot('agents', $request->input('agents', []));
$item->auditedSyncWithOrder('instruments', $request->input('instruments', []));
$item->auditedSync('languages', $request->input('languages', []));
$item->auditedAttach('places', $place);
$item->auditedDetach('places', $place);
```

### API

[](#api)

MethodUse case`auditedAttach(string $relation, $id, array $attrs = [], bool $touch = true)`Single (or batch) attach with audit`auditedDetach(string $relation, $ids = null, bool $touch = true): int`Detach with audit. `null` detaches all.`auditedSync(string $relation, $ids, bool $detaching = true): array`Full sync, equivalent to `sync()``auditedSyncWithoutDetaching(string $relation, $ids): array`Wrapper around `auditedSync(..., false)``auditedToggle(string $relation, $ids, bool $touch = true): array`Toggle with audit`auditedSyncWithOrder(string $relation, array $ids, string $orderColumn = 'order'): array`Ordered sync — smart-diff, silent reorder`auditedSyncRoledPivot(string $relation, array $rows, string $roleAttribute = 'role', string $defaultRole = 'creator'): array`Sync where identity is `(related_id, role)`. Role change = detach + attach.Each method is wrapped in a transaction so that pivot mutation and audit write succeed or fail atomically.

#### Audit payload

[](#audit-payload)

```
{
  "action":        "attach" | "detach" | "update",
  "relation":      "agents",
  "role":          "creator",
  "related_id":    42,
  "related_type":  "App\\Models\\Agent",
  "related_label": "John Doe"
}
```

The audit `description` is `relation_attach`, `relation_detach`, or `relation_update`, and `subject_type` / `subject_id` always point to the parent model.

### Important: do not use `Auditable` on pivot models

[](#important-do-not-use-auditable-on-pivot-models)

The recommended strategy is **parent-side audits only**. Pivot models (those extending `Illuminate\Database\Eloquent\Relations\Pivot`) should **not** use `Auditable`. Otherwise, a single `attach()`/`detach()` produces two audit entries: one parent-side (from `HasAuditedRelations`) and one pivot-side (from the pivot's `Auditable`).

### Migration guide for existing installations

[](#migration-guide-for-existing-installations)

If you currently rely on pivot-side `Auditable`, migrate as follows:

1. Locate pivot models using `Auditable` whose parent has, or will have, `HasAuditedRelations`: ```
    grep -rln "use App\\\\Traits\\\\Auditable" app/Models/ | xargs grep -l "extends Pivot"
    ```
2. Locate raw `sync()` / `attach()` / `detach()` / legacy `syncWithOrder` / `syncRoledPivot` calls in controllers that operate on audited relations: ```
    grep -rn "->sync(\|->attach(\|->detach(\|syncWithOrder\|syncRoledPivot" app/Http/Controllers/ --include="*.php"
    ```
3. Replace those calls with the `audited*` equivalents (`auditedSync`, `auditedSyncWithOrder`, `auditedSyncRoledPivot`).
4. Remove `use Auditable;` from the matching pivot models — both the trait use and the `App\Traits\Auditable` import.
5. Add `HasAuditedRelations` to any parent model not yet using it.

After migration, audited operations emit a single parent-side audit entry per affected related record.

Ordered Pivot Relationships
---------------------------

[](#ordered-pivot-relationships)

This package provides functionality to maintain order in many-to-many (pivot) relationships. This abstraction allows you to preserve the selection order of related models, which is particularly useful for forms where the order of selection matters.

> **Deprecation note (audited workflows):** the `syncWithOrder()` helpers in `HasOrderedPivot` and `HandlesOrderedPivot` are now smart-diff and phantom-event-free, but they do **not** produce audit entries. For audited operations use [`HasAuditedRelations::auditedSyncWithOrder()`](#audited-relations) on the parent model instead. The legacy helpers remain available for unaudited use cases and to keep existing installations working unchanged.

### Quick Start

[](#quick-start)

#### 1. Create migration for order column:

[](#1-create-migration-for-order-column)

```
php artisan make:ordered-pivot-migration paper_user --order-column=order --after=user_id
```

This creates a migration that adds an `order` column to the `paper_user` pivot table.

#### 2. Update your model:

[](#2-update-your-model)

```
