Урок 08

Полиморфные связи

Что это

Полиморфная связь позволяет одной модели принадлежать нескольким другим моделям. Например, комментарий может быть у поста, у видео и у опроса — одна таблица comments, но разные родители.

Структура таблицы

Вместо post_id используются две колонки:

  • commentable_id — ID родителя
  • commentable_type — класс родителя

Миграция:

$table->morphs('commentable');

Это создаёт обе колонки и индекс.

Модель Comment

public function commentable()
{
    return $this->morphTo();
}

Модели Post, Video, Poll

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

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

$comment = Comment::find(1);
$parent = $comment->commentable; // Post или Video

$post = Post::find(1);
foreach ($post->comments as $comment) {
    echo $comment->body;
}

Полиморфный один к одному

public function image()
{
    return $this->morphOne(Image::class, 'imageable');
}

Полиморфный многие ко многим

public function tags()
{
    return $this->morphToMany(Tag::class, 'taggable');
}

Миграция:

$table->morphs('taggable');

Когда использовать

Полиморфизм удобен, когда логика обработки одинакова для разных типов. Если логика сильно различается — лучше отдельные таблицы.