mountainclans/laravel-polymorphic-model

Пакет, добавляющий возможность хранить в одной таблице модели разных типов, имеющих общего предка

1.0.1-beta 2025-06-30 12:52 UTC

This package is not auto-updated.

Last update: 2025-07-03 12:13:25 UTC


README

Пакет, добавляющий возможность хранить в одной таблице модели разных типов, имеющих общего предка

Установка

Установите пакет при помощи Composer:

composer require mountainclans/laravel-polymorphic-model

Использование

Добавьте в родительский класс использование трейта PolymorphicModel и константу ALLOWED_TYPES, содержащую в себе допустимые типы классов-наследников.

Также для корректного сохранения модели в той же таблице явно укажите в родителе, какую таблицу он использует.

Убедитесь, что в таблице присутствует поле type.

use MountainClans\LaravelPolymorphicModel\Traits\PolymorphicModel;

class YourParentModel {
    use PolymorphicModel;
    
    public const TYPE_TOP_BANNER = 'top_banner';
    public const TYPE_ADVANTAGES = 'advantages';
    
    public const ALLOWED_TYPES = [
        self::TYPE_TOP_BANNER => TopBannerSection::class,
        self::TYPE_ADVANTAGES => AdvantagesSection::class,
    ];
    
    protected $table = 'your_parent_model';
}

В классах-наследниках переопределите функцию getInstanceType, возвращающую тип:

use MountainClans\LaravelPolymorphicModel\Traits\PolymorphicModel;

class TopBannerSection extends YourParentModel{
    protected function getInstanceType(): string
    {
        return static::TYPE_TOP_BANNER;
    }
}

Теперь Вы можете создавать класс-наследник напрямую и он будет сохранён в родительской таблице.

$model = new TopBannerSection();
...
$model->save();

Вы можете извлекать в рамках одного запроса любых наследников основной модели:

$collection = YourParentModel::withSubclasses()->get();

Или извлекать только модели нужного класса:

$collection = TopBannerSection::get();

Или указать нужные типы в запросе с использованием where и других конструкций:

$collection = YourParentModel::whereIn('type', [
    self::TYPE_TOP_BANNER, 
    self::TYPE_ADVANTAGES
])->get()

Количество уровней наследования моделей не ограничено.

Атрибут RequiresOverride

Внутри себя трейт PolymorphicModel использует атрибут #[RequiresOverride].

Вы можете использовать его для того, чтобы явно пометить, какие методы ваших моделей должны быть переопределены в классах-наследниках.

Обязательно объявите в классе использование трейта CheckOverrides.

use MountainClans\LaravelPolymorphicModel\Traits\CheckOverrides;
use MountainClans\LaravelPolymorphicModel\Attributes\RequiresOverride;

class YourModel extends Model {
    use CheckOverrides;
    
    #[RequiresOverride]
    public function functionForOverride() {
        
    }
}

Если переопределение не сделано, в момент выполнения метода boot модели-наследника будет выброшено исключение RequiredOverrideNotExistsException.

Авторы

Лицензия

The MIT License (MIT). Please see License File for more information.