Полиморфные связи
Что это
Полиморфная связь позволяет одной модели принадлежать нескольким другим моделям. Например, комментарий может быть у поста, у видео и у опроса — одна таблица 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');
Когда использовать
Полиморфизм удобен, когда логика обработки одинакова для разных типов. Если логика сильно различается — лучше отдельные таблицы.