Полиморфное отношение к множеству одинаковых сущностей в Eloquent Laravel

У вас есть общая таблица (полиморфная) которая может хранить общие записи разных моделек.
Например у вас есть модель комментариев, которые есть у постов и у видео. И вы хотите комментарии к постам делить на обычные комментарии (одна коллекция) и премиум комментарии (другая коллекция).
Чтобы ресурс вам возвращал каждый из типов в отдельности.
По умолчанию связь идет через поля entity_id и entity_type
Через них и проходит вся магия. создавая отношения через

public function comments()
{
    return $this->morphMany(Comment::class, 'entity');
}

вы получаете записи комментариев связаных с данным классом. Связь с классом происходит автоматически по имени текущего класса и на нее нельзя влиять стандартными средствами.
Вы можете подумать что решение задачи заключается в подстановке другого type в колонку с классом, но к сожалению laravel eloqment такое не позволяет. Он позволяет лишь переименовать название поля type и id.

Какие есть варианты решения?

Путей несколько. Во первых а для чего вам понадобилось дробить полиморфное отношение? Быть может вам следует сразу создать отдельную сущность. В нашем примере теоретически можно завести отдельную модель Премиум комментарии и связать ее с таблицей обычных комментариев
Но поле связки entity_type - будет хранить название модели с которой идет связь, а оно будет то же самое, а значит что заводить нужно и таблицу и дублировать все входные и выходные механизмы.

Можно пойти другим путем.

Создать виртуальную модель поста, наследуя обычный пост, связав отношение через отдельный метод. Да, тип связи у вас будет новый. По сути вы создали отдельные посты с ссылкой на основную таблицу постов. Но теперь проблема появляется в том, как получить данные связанные с постом при помощи ресурса. Можно конечно построить отношение между основной и виртуальной моделью, это будет весьма хардкорный, но достижимый путь.
Самое оптимальное видимое решение - разделить полиморфные отношения через дополнительный параметр. Физически - нужно будет в полиморфную модель создать дополнительную колонку, вид комментария. Для всех других связей она будет по умолчанию пуста. У вас также останется маневр, если вы захотите добавить аналогичное разделение на теже самые или новые категории в связки с видео или будущими комментируемыми сущностями. А чтобы держать удобной получение комментариев с разным типом - можете создать себе дополнительные функции

public function logos()
{
    return $this->photos()->where('gallery', 'logo');
}
public function certificates()
{
    return $this->photos()->where('gallery', 'certificate');
}
public function galleryes()
{
    return $this->photos()->where('gallery', 'gallery');
}

При этом прежняя функция comments также будет работать и вернет вам все комментарии, на случай если где-либо оно вам понадобится. Что весьма удобно.
Ну и дополнительно можно пойти самым обычным путем и эмулировать полиморфное отношение вручную,

public function products()
{
    return $this->hasMany(Products::class,'entity_id')->where('entity_type','premium');
}

 

по мотивам

https://laracasts.com/discuss/channels/general-discussion/multiple-polymorphic-relations-on-one-model

  • Автор: kosmom
  • Рейтинг: 0
  • Просмотров: 405
  • Комментариев: 0
  • Создан: 12.04.2021 18:09

Комментарии (0)

Ваши предложения и пожелания пишите на pro@kosmom.ru

Теги

backup bootstrap eloquent excel html ios javascript keep-alive laravel mvp php scroll timestamp undefined vue vuetify watch безопасность биометрический паспорт ваша любаша для путешествий загран на 10 лет загран паспорт загранпаспорт нового образца как заполнить анкеты кеширование логирование мцф образец заполнения антеты паспорт для путешествий паспорт нового поколения печать продукт проектирование прокси ремонт ремонт в апартаментах ремонт нежилого помещения самокат сколько стоил ремонт апартаментов спорт стандарты таблица хостинг цена ремонта юзабилити

Случайный пост

20.06.2020 14:20
Избегайте исключений в английском языке при написании сущностей