





Полиморфные отношения
Table Structure
Полиморфные отношения позволяют модели принадлежать нескольким другим моделям в одной ассоциации. Например, представьте, что пользователи вашего приложения могут «комментировать» как сообщения, так и видео. Используя полиморфные отношения, вы можете использовать одну таблицу комментариев для обоих этих сценариев. Во-первых, давайте рассмотрим структуру таблицы, необходимую для построения этой связи:
posts
id - integer
title - string
body - text
videos
id - integer
title - string
url - string
comments
id - integer
body - text
commentable_id - integer
commentable_type - string
Следует отметить два важных столбца: столбцы commentable_id и commentable_type в таблице комментариев. Столбец commentable_id будет содержать значение идентификатора публикации или видео, а столбец commentable_type будет содержать имя класса модели-владельца. Столбец commentable_type определяет, как ORM определяет, какой «тип» модели-владельца возвращать при доступе к комментируемому отношению.
Model Structure
Затем давайте рассмотрим определения модели, необходимые для построения этой связи:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
/**
* Get all of the owning commentable models.
*/
public function commentable()
{
return $this->morphTo();
}
}
class Post extends Model
{
/**
* Get all of the post's comments.
*/
public function comments()
{
return $this->morphMany('App\Comment', 'commentable');
}
}
class Video extends Model
{
/**
* Get all of the video's comments.
*/
public function comments()
{
return $this->morphMany('App\Comment', 'commentable');
}
}
Получение полиморфных отношений Как только ваша таблица базы данных и модели определены, вы можете получить доступ к отношениям через свои модели. Например, чтобы получить доступ ко всем комментариям к публикации, мы можем использовать динамическое свойство комментариев:
$post = App\Post::find(1);
foreach ($post->comments as $comment) {
//
}
Вы также можете получить владельца полиморфного отношения из полиморфной модели, обратившись к имени метода, который выполняет вызов morphTo. В нашем случае это комментируемый метод в модели Comment. Итак, мы получим доступ к этому методу как к динамическому свойству:
$comment = App\Comment::find(1);
$commentable = $comment->commentable;
Отношение commentable в модели Comment вернет либо экземпляр Post, либо Video, в зависимости от того, какой тип модели владеет комментарием. См. Эту ссылку: полиморфные отношения:
Вы можете записать так:
+---------+----------------+-------------------+
| user_id | commentable_id | commentable_type |
+---------+----------------+-------------------+
| 1 | 1 | App\Post |
| 1 | 2 | App\Post |
| 1 | 3 | App\Post |
| 1 | 1 | App\Video |
| 1 | 2 | App\Video |
| 1 | 3 | App\Video |
+---------+----------------+-------------------+
Отношение MorphMany имеет следующую сигнатуру функции:
public function morphMany($related, $name, $type = null, $id = null, $localKey = null)
{
//
}
Где:
$related (требуется): относится к связанной модели. например: User::class.$name (требуется): имя полиморфного отношения, например commentable.$type (необязательно): настроить поле {relation}_type для поиска при выполнении запроса.$id (необязательно): настроить поле {relation}_id для поиска при выполнении запроса.$localKey (необязательно): настроить локальный ключ (по умолчанию id) для поиска при выполнении запроса.Итак, используя пример, показанный в документации Laravel, если вы хотите использовать другую структуру таблицы для таблицы comments из этой:
posts
id - integer
title - string
body - text
videos
id - integer
title - string
url - string
comments
id - integer
body - text
commentable_id - integer
commentable_type - string
к этому:
posts
id - integer
title - string
body - text
videos
id - integer
title - string
url - string
comments
id - integer
body - text
foo - integer // the index to look
bar - string // the type to match
Вам нужно будет определить свои отношения следующим образом:
Post.php
public function comments()
{
return $this->morphMany(Comment::class, 'commentable', 'foo', 'bar');
}
Video.php
public function comments()
{
return $this->morphMany(Comment::class, 'commentable', 'foo', 'bar');
}
Комментарий.php
public function commentable()
{
return $this->morphTo('commentable');
}
Отметьте это другой ответ.
спасибо за ответ @Keval Mangukiya, но мне нужны параметры внутри функции $ this-> morphMany (), документация не уточняет параметры этой функции