Поле morphs
Метод morphs в миграциях Laravel создаёт два столбца: {name}_id типа unsignedBigInteger и {name}_type типа string. Эти поля используются для реализации полиморфных отношений, когда одна модель может принадлежать нескольким другим моделям. Первым параметром передаётся имя связи, которое определяет префикс для создаваемых колонок.
Синтаксис
<?php
Schema::create('table_name', function (Blueprint $table) {
$table->morphs('relation_name');
});
?>
Пример
Давайте создадим таблицу 'comments', которая будет содержать полиморфные поля для связи с различными моделями:
<?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('text');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('comments');
}
};
?>
В результате будут созданы поля 'commentable_id' и 'commentable_type'.
Пример
Теперь создадим модели, которые будут использовать эти поля для полиморфной связи:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
public function commentable()
{
return $this->morphTo();
}
}
?>
<?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\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
}
?>
Пример
Давайте создадим комментарии для разных моделей:
<?php
namespace App\Http\Controllers;
use App\Models\Article;
use App\Models\User;
use App\Models\Comment;
class CommentController extends Controller
{
public function create()
{
$article = Article::find(1);
$comment1 = new Comment(['text' => 'article comment']);
$article->comments()->save($comment1);
$user = User::find(1);
$comment2 = new Comment(['text' => 'user comment']);
$user->comments()->save($comment2);
echo 'Comments created successfully';
}
}
?>
Результат выполнения кода:
"Comments created successfully"
После выполнения в таблице 'comments' будут созданы записи с заполненными полями 'commentable_id' и 'commentable_type'.
Пример
Давайте получим комментарии для конкретной модели:
<?php
namespace App\Http\Controllers;
use App\Models\Article;
class CommentController extends Controller
{
public function show()
{
$article = Article::find(1);
$comments = $article->comments;
foreach ($comments as $comment) {
echo $comment->text;
}
}
}
?>
Результат выполнения кода:
"article comment"
Смотрите также
-
метод
nullableMorphs,
который создаёт nullable версию полиморфных полей -
метод
uuidMorphs,
который создаёт полиморфные поля с UUID типом -
метод
morphTo,
который определяет обратную полиморфную связь в модели -
метод
morphMany,
который определяет полиморфную связь "один ко многим"