Метод morphTo
Метод morphTo определяет обратную полиморфную связь в Eloquent. Он используется в дочерней модели, которая содержит два специальных поля: {relation}_type (хранит имя класса родительской модели) и {relation}_id (хранит идентификатор родительской записи). Метод возвращает экземпляр BelongsTo и позволяет получить родительскую модель динамически, в зависимости от значения поля type.
Синтаксис
<?php
Model::morphTo($name, $type, $id);
?>
Пример
Давайте создадим модели для полиморфной связи. У нас будут модели Article и User, к которым можно оставлять комментарии. Сначала создадим миграцию для таблицы комментариев:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->morphs('commentable');
$table->text('body');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('comments');
}
};
?>
Теперь определим модель Comment с методом morphTo:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
public function commentable()
{
return $this->morphTo();
}
}
?>
В родительских моделях определим обратную связь с помощью morphMany:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
}
?>
Пример
Давайте получим комментарии для статьи и определим, к какой модели они принадлежат:
<?php
namespace App\Http\Controllers;
use App\Models\Article;
use App\Models\Comment;
class CommentController extends Controller
{
public function index()
{
$article = Article::find(1);
$comments = $article->comments;
foreach ($comments as $comment) {
echo $comment->body;
echo $comment->commentable->title;
}
}
}
?>
Результат выполнения кода:
"Great article!"
"Laravel Basics"
"Very helpful"
"Laravel Basics"
Пример
Метод morphTo позволяет указать имя отношения явно, если оно отличается от имени метода:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
public function parent()
{
return $this->morphTo('commentable');
}
}
?>
Смотрите также
-
метод
morphMany,
который определяет один-ко-многим полиморфную связь -
метод
morphOne,
который определяет один-к-одному полиморфную связь -
метод
morphToMany,
который определяет многие-ко-многим полиморфную связь -
метод
morphedByMany,
который определяет обратную многие-ко-многим полиморфную связь