Полиморфные отношения

Один к одному (полиморфное)

Миграции для моделей
posts
    id - integer
    name - string

users
    id - integer
    name - string

images
    id - integer
    url - string
    imageable_id - integer
    imageable_type - string
create_users_table
public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });
    }
create_images_table
public function up()
    {
        Schema::create('images', function (Blueprint $table) {
            $table->id();
            $table->string('url');
            $table->integer('imageable_id')->nullable();
            $table->string('imageable_type')->nullable();
            $table->timestamps();
        });
    }
create_posts_table
public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });
    }
app/Models/Image.php
public function imageable()
    {
        return $this->morphTo();
    }
app/Models/Post.php
public function image()
    {
        return $this->morphOne(Image::class, 'imageable');
    }
app/Models/User.php
public function image()
    {
        return $this->morphOne(Image::class, 'imageable');
    }

Создание отношений «Один-к-Одному» (полиморфное)

// выбираем пост с айди 1
$post = Post::find(1);
// создаём изображение
$image = new Image([
    'url' => 'some image url'
]);
// связываем наше изображение с постом и сохраняем его
$image->imageable()->associate($post);
$image->save();

Отсоединение связи «Один-к-Одному» (полиморфное)

$post = Post::find(1);
$image = Image::find(1);
// отсоединяем imageable(post/user) от изображения и сохраняем его
$image->imageable()->dissociate($post);
$image->save();

Получение данных «Один-к-Одному» (полиморфное)

// выбираем пост с айди 1
$post = Post::find(1);
// получаем его image
$image = $post->image;
// выбираем изображение с айди 1
$image = Image::find(1);
// получаем его imageble (post/user)
$imageable = $image->imageable;

Удаление данных «Один-к-Одному» (полиморфное)

// выбираем пост с айди 1
$post = Post::find(1);
// удаляем пренадлежащее ему изображение
$post->image()->delete();

Один ко многим (полиморфное)

Миграции для моделей
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
create_comments_table
Schema::create('comments', function (Blueprint $table) {
    $table->increments('id');
    $table->string("body");
    $table->integer('commentable_id')->nullable();
    $table->string("commentable_type")->nullable();
    $table->timestamps();
});
create_videos_table
Schema::create('videos', function (Blueprint $table) {
    $table->increments('id');
    $table->string("name");
    $table->timestamps();
});
create_posts_table
Schema::create('posts', function (Blueprint $table) {
    $table->increments('id');
    $table->string("name");
    $table->timestamps();
});
app/Models/Post.php
public function comments()
    {
        return $this->morphMany(Comment::class, 'commentable');
    }
app/Models/Video.php
public function comments()
    {
        return $this->morphMany(Comment::class, 'commentable');
    }
public function commentable()
    {
        return $this->morphTo();
    }

Операции с данными идентичны обычным (не полиморфным) связям

Многие ко многим (полиморфное)

Миграции для моделей
posts
    id - integer
    name - string

videos
    id - integer
    name - string

tags
    id - integer
    name - string

taggables
    tag_id - integer
    taggable_id - integer
    taggable_type - string
create_taggables_table
Schema::create('taggables', function (Blueprint $table) {
    $table->integer("tag_id");
    $table->integer("taggable_id")->nullable();
    $table->string("taggable_type")->nullable();
});
create_tags_table
Schema::create('tags', function (Blueprint $table) {
    $table->increments('id');
    $table->string("name");
    $table->timestamps();
});
create_videos_table
Schema::create('videos', function (Blueprint $table) {
    $table->increments('id');
    $table->string("name");
    $table->timestamps();
});
create_posts_table
Schema::create('posts', function (Blueprint $table) {
    $table->increments('id');
    $table->string("name");
    $table->timestamps();
});
app/Models/Post.php
public function tags()
    {
        return $this->morphToMany(Tag::class, 'taggable');
    }
app/Models/Video.php
public function tags()
    {
        return $this->morphToMany(Tag::class, 'taggable');
    }
app/Models/Tag.php
public function posts()
    {
        return $this->morphedByMany(Post::class, 'taggable');
    }

public function videos()
    {
        return $this->morphedByMany(Video::class, 'taggable');
    }

Операции с данными идентичны обычным (не полиморфным) связям

Last updated