Метод morphToMany
Метод morphToMany используется в моделях Eloquent для определения полиморфной связи "многие ко многим". Он позволяет одной модели принадлежать множеству других моделей через промежуточную таблицу, при этом типы связываемых моделей могут быть разными. Первым параметром передаётся связанный класс, вторым - имя метода связи, третьим - имя таблицы связей, четвёртым - внешний ключ полифической модели.
Синтаксис
<?php
Model::morphToMany($related, $name, $table, $foreignPivotKey, $relatedPivotKey);
?>
Пример
Давайте определим полиморфную связь "многие ко многим" для модели Tag. Пусть теги могут принадлежать как статьям, так и видео:
<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
class Tag extends Model
{
public function articles()
{
return $this->morphToMany(Article::class, 'taggable');
}
public function videos()
{
return $this->morphToMany(Video::class, 'taggable');
}
}
?>
Пример
Теперь определим обратную связь в модели Article:
<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
class Article extends Model
{
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
}
?>
Пример
Аналогично определим связь в модели Video:
<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
class Video extends Model
{
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
}
?>
Пример
Создадим миграцию для полиморфной таблицы связей:
<?php
use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;
return new class extends Migration
{
public function up()
{
Schema::create('taggables', function (Blueprint $table) {
$table->id();
$table->foreignId('tag_id')->constrained()->onDelete('cascade');
$table->morphs('taggable');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('taggables');
}
};
?>
Пример
Прикрепим теги к статье и получим их:
<?php
use AppModelsArticle;
use AppModelsTag;
$article = Article::find(1);
$tag = Tag::find(1);
$article->tags()->attach($tag);
$res = $article->tags;
print_r($res->toArray());
?>
Результат выполнения кода:
[
{"id":1,"name":"php","created_at":"2025-01-01 10:00:00","updated_at":"2025-01-01 10:00:00"},
{"id":2,"name":"laravel","created_at":"2025-01-01 10:00:00","updated_at":"2025-01-01 10:00:00"}
]
Пример
Получим все теги, связанные с видео:
<?php
use AppModelsVideo;
$video = Video::find(5);
$res = $video->tags()->where('name', 'php')->get();
foreach ($res as $tag) {
echo $tag->name . "\n";
}
?>
Результат выполнения кода:
"php"
Пример
Открепим все теги от статьи:
<?php
use AppModelsArticle;
$article = Article::find(1);
$article->tags()->detach();
?>
Смотрите также
-
метод
morphTo,
который определяет обратную полиморфную связь -
метод
morphOne,
который определяет полиморфную связь "один к одному" -
метод
morphMany,
который определяет полиморфную связь "один ко многим" -
метод
morphedByMany,
который определяет обратную полиморфную связь "многие ко многим"