PHPackages                             oxyaction/yii2-polymorphic-relation-behavior - 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. oxyaction/yii2-polymorphic-relation-behavior

ActiveYii2-extension

oxyaction/yii2-polymorphic-relation-behavior
============================================

Establishes polymorphic relations

1.0.0(9y ago)1125.3k↓50%4[1 issues](https://github.com/Oxyaction/yii2-polymorphic-relation-behavior/issues)MITPHPPHP &gt;=5.4.0

Since Mar 12Pushed 9y ago3 watchersCompare

[ Source](https://github.com/Oxyaction/yii2-polymorphic-relation-behavior)[ Packagist](https://packagist.org/packages/oxyaction/yii2-polymorphic-relation-behavior)[ Docs](https://github.com/Oxyaction/yii2-polymorphic-relation-behavior)[ RSS](/packages/oxyaction-yii2-polymorphic-relation-behavior/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (1)Dependencies (2)Versions (2)Used By (0)

Yii2 RelatedPolymorphic Behavior
--------------------------------

[](#yii2-relatedpolymorphic-behavior)

This behavior helps to establish polymorphic behaviors easily. Forget about endless dictionary tables in your storage.

---

[![Build Status](https://camo.githubusercontent.com/5b30f47ebeacb9123820c338366f23bc56f3ad2c41cd7e5eab1ebf3fe8b5e20e/68747470733a2f2f7472617669732d63692e6f72672f4f7879616374696f6e2f796969322d706f6c796d6f72706869632d72656c6174696f6e2d6265686176696f722e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/Oxyaction/yii2-polymorphic-relation-behavior)[![Latest Stable Version](https://camo.githubusercontent.com/540d07db12f499bf41d1abb99564e548b37800cbe0714b9bc62705e703fa2f2c/68747470733a2f2f706f7365722e707567782e6f72672f6f7879616374696f6e2f796969322d706f6c796d6f72706869632d72656c6174696f6e2d6265686176696f722f762f737461626c65)](https://packagist.org/packages/oxyaction/yii2-polymorphic-relation-behavior)[![Latest Unstable Version](https://camo.githubusercontent.com/e2acd3b053f3d9cd7eddf7a05b6361394009724dcf9c2f9072665a9c51ae55ac/68747470733a2f2f706f7365722e707567782e6f72672f6f7879616374696f6e2f796969322d706f6c796d6f72706869632d72656c6174696f6e2d6265686176696f722f762f756e737461626c65)](https://packagist.org/packages/oxyaction/yii2-polymorphic-relation-behavior)[![License](https://camo.githubusercontent.com/7507cecc9f9174ecd30fee41ea599aa0cdebb367697eca9c84702e5db16954aa/68747470733a2f2f706f7365722e707567782e6f72672f6f7879616374696f6e2f796969322d706f6c796d6f72706869632d72656c6174696f6e2d6265686176696f722f6c6963656e7365)](https://packagist.org/packages/oxyaction/yii2-polymorphic-relation-behavior)

### Problem

[](#problem)

Often you have some entity related to multiple entities in your system. For example `Comment` entity can belong to both `Article`, `Photo`, `Post` etc. You can create a comment table for each of this entities (`ArticleComment`, `PhotoComment`, `PostComment`), but this solution is not so good and not DRY at all.

The best solution will be creating the single `Comment` entity table and establishing polymorphic relations. The `comment` table is required to have `type` column that will indicate to which entity type comment belongs and `external_id` column that will be used as foreign key column.

```
class Article extends ActiveRecord
{
    const ARTICLE = 1;

    public function behaviors()
    {
        return [
            'polymorphic' => [
                'class' => RelatedPolymorphicBehavior::className(),
                'polyRelations' => [
                    'comments' => Comment::className()
                ],
                'polymorphicType' => self::TYPE_ARTICLE
            ]
        ];
    }
}

class Photo extends ActiveRecord
{
    const PHOTO = 2;

    public function behaviors()
    {
        return [
            'polymorphic' => [
                'class' => RelatedPolymorphicBehavior::className(),
                'polyRelations' => [
                    'comments' => Comment::className()
                ],
                'polymorphicType' => self::TYPE_PHOTO
            ]
        ];
    }
}
```

Then you can query relations as always

```
$article->comments;
$photo->comments;

```

### Options

[](#options)

#### Has many

[](#has-many)

Short:

```
...
public function behaviors()
{
    return [
        'polymorphic' => [
            'class' => RelatedPolymorphicBehavior::className(),
            'polyRelations' => [
                'comments' => Comment::className()
            ],
            'polymorphicType' => 'article'
        ]
    ];
}
...
```

Same as

```
public function behaviors()
{
    return [
        'polymorphic' => [
            'class' => RelatedPolymorphicBehavior::className(),
            'polyRelations' => [
                'comments' => [
                    'type' => RelatedPolymorphicBehavior::HAS_MANY,
                    'class' => Comment::className(),
                    'pkColumnName' => 'id',
                    'foreignKeyColumnName' => 'external_id',
                    'typeColumnName' => 'type',
                    'deleteRelated' => false,
                ]
            ],
            'polymorphicType' => 'article'
        ]
    ]
}
```

#### Many to many

[](#many-to-many)

Often we need to establish polymorphic relation with many to many. in this case `type` and `external_id` columns will be in junction table.

```
public function behaviors()
{
    return [
        'polymorphic' => [
            'class' => RelatedPolymorphicBehavior::className(),
            'polyRelations' => [
                'tags' => [
                    'type' => RelatedPolymorphicBehavior::MANY_MANY,
                    'class' => Tag::className(),
                    'viaTable' => 'taggable_tag',
                ]
            ],
            'polymorphicType' => 'article'
        ]
    ]
}
```

All available options:

```
public function behaviors()
{
    return [
        'polymorphic' => [
            'class' => RelatedPolymorphicBehavior::className(),
            'polyRelations' => [
                'tags' => [
                    'type' => RelatedPolymorphicBehavior::MANY_MANY,
                    'class' => Tag::className(),
                    'viaTable' => 'taggable_tag',
                    'pkColumnName' => 'id',
                    'foreignKeyColumnName' => 'external_id',
                    'otherKeyColumnName' => 'tag_id',
                    'typeColumnName' => 'type',
                    'relatedPkColumnName' => 'id',

                ]
            ],
            'polymorphicType' => 'photo'
        ]
    ]
}
```

Some options can be set on per behavior or per relation level. For example `polymorphicType` from example above is set on behavior level, while `typeColumnName` on relation level. In case if you set option on behavior level you won't need to duplicate it for multiple relations while relation option will take precedence.

OptionDescriptionRequiredDefaultLevelType`type``RelatedPolymorphicBehavior::MANY_MANY` or `RelatedPolymorphicBehavior::HAS_MANY`Yesrelation`class`related model class nameYesrelation`polymorphicType`type of the polymorphic entityYesbehavior, relation`viaTable`junction table nameYesrelation`MANY MANY``pkColumnName`source model pk column namefetched from schemabehavior, relation`foreignKeyColumnName`foreign key`external_id`behavior, relation`typeColumnName`column name for type of polymorphic model`type`behavior, relation`deleteRelated`delete related values, after removing primary modelfalserelation`HAS MANY``otherKeyColumnName`related model's foreign key column name in junction tablefetched from schemarelation`MANY MANY``relatedPkColumnName`related model's pk column namefetched from schemarelation`MANY MANY`#### Final example

[](#final-example)

```
class Article extends ActiveRecord {
    public function behaviors()
    {
        return [
            'polymorphic' => [
                'class' => RelatedPolymorphicBehavior::className(),
                'polyRelations' => [
                    'tags' => [
                        'type' => RelatedPolymorphicBehavior::MANY_MANY,
                        'class' => Tag::className(),
                        'viaTable' => 'taggable_tag',
                    ],
                    'images' => [
                        'type' => RelatedPolymorphicBehavior::HAS_MANY,
                        'class' => Image::className(),
                    ],
                    'comments' => [
                        'type' => RelatedPolymorphicBehavior::HAS_MANY,
                        'class' => Comment::className(),
                    ],
                ],
                'polymorphicType' => 'article',
                'pkColumnName' => 'ID',
                'foreignKeyColumnName' => 'some_external_id',
                'typeColumnName' => 'entity_type',
            ]
        ]
    }
}
```

This will assume that `taggable_tag`, `image` and `comment` tables have `some_external_id` and `entity_type` columns, for `Article`entity it will be filled with `article` value and `Article` primary key column name is `ID`.

#### Warning

[](#warning)

Since `external_id` of the polymorphic target entity links to multiple entities, you can not use foreign key constraints and need to check data consistency on application level.

###  Health Score

34

—

LowBetter than 77% of packages

Maintenance18

Infrequent updates — may be unmaintained

Popularity34

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity58

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

3355d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/553fec0523a2fe628dd18ab1144ede7983071baf1df1c9afc0120c0ee913e80f?d=identicon)[Oxyaction](/maintainers/Oxyaction)

---

Top Contributors

[![Oxyaction](https://avatars.githubusercontent.com/u/1942242?v=4)](https://github.com/Oxyaction "Oxyaction (15 commits)")

---

Tags

yii2yii2-behaviorsyii2-extensionbehaviouryii2Behavioryii 2relationpolymorphic

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/oxyaction-yii2-polymorphic-relation-behavior/health.svg)

```
[![Health](https://phpackages.com/badges/oxyaction-yii2-polymorphic-relation-behavior/health.svg)](https://phpackages.com/packages/oxyaction-yii2-polymorphic-relation-behavior)
```

###  Alternatives

[voskobovich/yii2-many-many-behavior

This behavior makes it easy to maintain relations many-to-many in the your ActiveRecord model.

112181.9k2](/packages/voskobovich-yii2-many-many-behavior)[arogachev/yii2-many-to-many

Many-to-many ActiveRecord relation for Yii 2 framework

3541.2k4](/packages/arogachev-yii2-many-to-many)[mootensai/yii2-relation-trait

Yii 2 Models load with relation, &amp; transaction save with relation

47220.3k9](/packages/mootensai-yii2-relation-trait)[softark/yii2-dual-listbox

Bootstrap Dual Listbox Widget for Yii 2

20144.4k11](/packages/softark-yii2-dual-listbox)[liyunfang/yii2-upload-behavior

Upload behavior for Yii 2

161.7k](/packages/liyunfang-yii2-upload-behavior)

PHPackages © 2026

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