PHPackages                             carono/yii2-pivot - 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. carono/yii2-pivot

ActiveYii2-extension[Utility &amp; Helpers](/categories/utility)

carono/yii2-pivot
=================

Trait for pivoting models

1.0.0(4mo ago)021BSD-3-ClausePHPPHP ^8.1

Since Jan 7Pushed 4mo agoCompare

[ Source](https://github.com/carono/yii2-pivot)[ Packagist](https://packagist.org/packages/carono/yii2-pivot)[ GitHub Sponsors](https://github.com/sponsors/yiisoft)[ OpenCollective](https://opencollective.com/yiisoft)[ RSS](/packages/carono-yii2-pivot/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (8)Versions (2)Used By (1)

`PivotTrait` is a Yii2 `ActiveRecord` trait that helps work with “pivot” (junction) tables in many-to-many relations: it can find/get pivot rows, stage pivot changes in an internal storage, and then persist them (insert/update) or delete them.

What it provides
----------------

[](#what-it-provides)

- Query helpers:
    - `findPivot($model, $pivotClass)` / `getPivot($model, $pivotClass, $condition = [])` to build/query a single pivot record between “this” model and a related model.
    - `findPivots($pivotClass)` / `getPivots($pivotClass, $condition = [])` to query all pivot rows for the current model (by its PK).
- In-memory staging (“storage”) of pivot operations:
    - `storagePivot($model, $pivotClass, $attributes = [])` and `storagePivots($models, $pivotClass, $attributes = [])` store related models (and optional extra pivot attributes) keyed by `spl_object_hash`.
    - `getPivotStorage()`, `getStoragePivots($pivotClass)`, `getStoragePivotAttribute($model, $pivotClass)`, `clearStorage($pivotClass)` to inspect/clear staged data.
- Persistence helpers:
    - `savePivots($clear = false, $condition = [])` iterates stored pivots and writes them, optionally clearing existing pivots first.
    - `addPivot($model, $pivotClass, $attributes = [])` upserts a pivot row: if found by key condition it updates attributes, otherwise inserts a new row.
    - `deletePivot($model, $pivotClass, $condition = [])` deletes a single pivot row for a given related model (plus extra condition).

How pivot keys are detected
---------------------------

[](#how-pivot-keys-are-detected)

The trait builds a pivot “condition” like: `[pivot_main_fk => this->PK, pivot_slave_fk => relatedModel->PK]`. Pivot key field names are resolved by checking the pivot table schema primary keys and trying to match foreign keys to the involved tables; if it cannot uniquely match by FK, it falls back to the first PK column as “main” and second PK column as “slave”.

Usage examples
--------------

[](#usage-examples)

### 1) Upsert a pivot row directly

[](#1-upsert-a-pivot-row-directly)

```
class User extends \yii\db\ActiveRecord {
    use PivotTrait;
}

$user = User::findOne(1);
$role = Role::findOne(5);

// Upsert pivot row (user_id, role_id) with extra attributes.
$user->addPivot($role, UserRole::class, ['created_at' => time()]);
```

This will update an existing `UserRole` record matching the computed condition, or create a new one otherwise.

### 2) Stage multiple pivots, then save them

[](#2-stage-multiple-pivots-then-save-them)

```
$user->storagePivots([$role1, $role2], UserRole::class, ['created_at' => time()]);
$user->savePivots();        // writes all staged items
$user->clearStorage(UserRole::class);
```

Staging stores models + attributes in an internal storage array, and `savePivots()` persists them by calling `addPivot()` for each entry.

### 3) Replace all pivots for a class (clear then insert)

[](#3-replace-all-pivots-for-a-class-clear-then-insert)

```
$user->storagePivots($newRoles, UserRole::class);
$user->savePivots(true); // $clear=true => delete existing pivots first, then add staged ones
```

When `$clear` is true, the trait deletes existing pivot rows for that pivot class before adding the staged ones.

Notes / assumptions
-------------------

[](#notes--assumptions)

- The trait assumes both the current model and related models have a single-column primary key (it uses `primaryKey()[0]`).
- The pivot table is expected to have a composite primary key with two columns (the code accesses `$pks[0]` and `$pks`).

If you share the pivot AR class (the junction `ActiveRecord`) and the two related AR models, a more concrete README-style snippet can be written with real class/table/column names.

###  Health Score

34

—

LowBetter than 77% of packages

Maintenance77

Regular maintenance activity

Popularity2

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity43

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

Unknown

Total

1

Last Release

125d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/6193985?v=4)[Александр Касьянов](/maintainers/carono)[@carono](https://github.com/carono)

---

Top Contributors

[![carono](https://avatars.githubusercontent.com/u/6193985?v=4)](https://github.com/carono "carono (2 commits)")

---

Tags

yii2extension

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm, Rector

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/carono-yii2-pivot/health.svg)

```
[![Health](https://phpackages.com/badges/carono-yii2-pivot/health.svg)](https://phpackages.com/packages/carono-yii2-pivot)
```

###  Alternatives

[vyants/yii2-daemon

Extension provides functionality for simple daemons creation and control

7859.0k](/packages/vyants-yii2-daemon)[dmstr/yii2-cookie-consent

Yii2 Cookie Consent Widget

1452.6k](/packages/dmstr-yii2-cookie-consent)[richardfan1126/yii2-js-register

Yii2 widget to register JS into view

1357.2k7](/packages/richardfan1126-yii2-js-register)

PHPackages © 2026

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