Сделал по доке One To One (Polymorphic), работает, но пока не въехал, когда это использовать, дайте простые задания, что бы я полностью разобрался именно для One To One (Polymorphic).
Что б не создавать много таблиц. У файла помимо пути есть еще и имя и размер возможно геолокацию подцепить захочешь создать миниатюру и т.д видишь сколько уже полей получается. А дальше еще можешь и в коментах захотеть картинки добавлять и еще где то
@Dimon2x Логично. Вот ты же аватарку режешь? + оригинальное изображение тоже где то хранить нужно соответсвенно уже как минимум 2 поля. Зачем тебе в каждой таблице создавать этих 2 поля если можно все вынести в одну таблицу которая будет отвечать за все файлы.
@nospiou @mkramer Вот что получилось, правильно ли я вообще думаю? модель Post PHP: <?php namespace App; use Illuminate\Database\Eloquent\Model; class Post extends Model { public function image() { return $this->morphOne('App\Image', 'imageable'); } } Полиморфная таблица посты Обращаюсь так PHP: $post = Post::find(1); $image = $post->image; dump($post); dump(User::find($post->user_id)); dump($image); Выводит коллекцию со статьёй, коллекцию с юзером и коллекцию с этими изображениями и потом я засуну в переменные нужные данные и передам их в вид и расставлю изображения в медиазапросы, я правильно понял суть это полиморфной связи?
Ну то что ты сохраняешь файл с оригинальным названием это не круто. Если появится новая картинка с тем же названием она пере запишет старую. Используй уникальные имена. А оригинальные храни в отдельном поле. На счет медиа запросов ну с таким маленьким интервалом это не нужно миниатюра + оригинал остальное по обстоятельствам.
@Dimon2x Если у тебя есть две модели которым нужна таблица (с общими полями). Например комменты могут быть и под аватаркой и под постом. Лайки могут быть и под аватаркой и под постом. И т.д. Все просто.
@nospiou Не понял, получается для этого понадобится 2 таблицы с коментами, в одной лежат коменты для аватарки, в другой для поста и в полиморфную таблицу в imageable_type указать модель, в imageable_id указать id коммента, а в дополнительные поля что?
Полиморфные связи используется когда тебе нужна таблица с одинаковой структурой для разных моделей. Притом это не обязательно должно быть 1к1. К примеру аватарка у тебя может быть всего одна (1 к 1) а у поста может быть много картинок (1 к многим) а таблицу ты будешь использовать одну. Вообщем вся суть в том что одна таблица используется для разных моделей ну а что бы можно было различить добавляются два дополнительных поля _id (id модели) и _type (тип модели в ларке по умолчанию это имя класса get_class(User::class) ну или this self внутри модели) но можно переназначит morphMap Не знаю как еще обьяснить.
@nospiou тогда для чего в доке добавили поле url? https://laravel.com/docs/5.7/eloquent-relationships#one-to-one-polymorphic-relations
Ну вот чтобы не надо было две таблицы с комментами, сохраняют тип модели, которая прокомментирована. А разработчики Ларки это дело автоматизировали. ну у тебя size-50, size-150, а у них url, чего не ясного-то? --- Добавлено --- И вместо imagable можно писать какой-нибудь commentable, если нужно. Главное, чтоб всё совпадало, где надо
Если раньше у тебя было user_id или post_id то сейчас ты используешь общее_название_id (можно не заморачиватся и делать owner_id или model_id в не зависимости от таблицы главное что бы суть передавало) ну и плюс добавляется type (owner_type model_type) больше в структуре различий никаких. А дополнительные поля какие нужны такие и делай.
@mkramer но ведь это же всё можно сделать обычными связями многие ко многим --- Добавлено --- @nospiou то есть полиморфная таблица, это аналог промежуточной?
Можно. Но тогда поле type нужно будет создавать самому + писать функции для работы а тут уже все готово. Когда ты пишешь $user->image ларка делает get_class($user) и получает тип (ну и соответсвенно добавляет в запрос SELECT WHERE _type=) --- Добавлено --- Нет. Это обычная таблица как в обычном 1 к 1 или 1 к многим только с полем type)
Не понял, причём тут многие-ко-многим. Но это и есть обычная связь, только нескольких таблиц с одной. Т.е. и у поста есть картинки, и у пользователя есть картинка, и у комментариев могут быть картинки, к примеру. А чтобы разобраться, какая картинка поста, какая пользователя, какая комментария, вводится дополнительное поле. Если писать самому, то туда даже не обязательно имя класса фигачить. Можно каким-либо другой признак. Но конкретно при Active Record (а Eloquent - это Active Record) удобно писать имя класса. Я когда-то сам до такой схемы с комментариями дошёл, сделал наработки на Yii2, где из коробки нету. В Laravel вот добавили из коробки, причём, недавно, насколько мне известно.
Как вывести посты разных моделей у которых 1 общий тег? Имеются модели изображения, видео, теги. Для тегов использовал полиморфные связи (Many To Many (Polymorphic)) всё по доке. PHP: class Tag extends Model { public function images() { return $this->morphedByMany('App\Image', 'taggable'); } public function videos() { return $this->morphedByMany('App\Video', 'taggable'); } } Пробую вывести пока так PHP: $tag = Tag::find(1); foreach ($tag->images as $image) { dump($image); } foreach ($tag->videos as $video) { dump($video); } Но этот вариант мне не нравится, как можно сделать одним циклом? Или вывести двумя циклами и объединить коллекции?
А конкретно какая задача? Вывести все модели, связанные с меткой в любом порядке? Или какая-нибудь пагинация предполагается? Смотришь задачу, придумываешь решение.
Ну вот если с пагинацией, и потенциально этих связей трындецки много, то Laravel уже не помощник (хотя, может @romach или @nosopiu меня поправят), и надо руками сначала запрашивать таблицу тэгов, а потом выделять модели и запрашивать их.
@Dimon2x, Простой (по моему мнению) пример использования полиморфных отношений: номер телефона в организации может быть закреплен: 1. либо за сотрудником (Иванов Иван - менеджер, который сидит на попе ровно на протяжении долгого времени и не хочет увольняться, и где он сидит нам не важно, для чистоты примера) 2. либо за местом (например Пост охраны 1 или 2 этажа - где постоянная текучка кадров, и сотрудника конкретного закрепить не получается, да это и не к чему, и не мы решаем кому там сидеть а охранное предприятие, главное не кто там сидит, а где этот Пост). Тут мы связываем две разные модели сотрудник, место с моделью номер.