mountainclans / laravel-polymorphic-model
Пакет, добавляющий возможность хранить в одной таблице модели разных типов, имеющих общего предка
Fund package maintenance!
Mountain Clans
Requires
- php: ^8.2
- illuminate/contracts: ^10.0||^11.0||^12.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.1.1||^7.10.0
- orchestra/testbench: ^10.0.0||^9.0.0||^8.22.0
- pestphp/pest: ^3.0
- pestphp/pest-plugin-arch: ^3.0
- pestphp/pest-plugin-laravel: ^3.0
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.