• Время чтения ~3 мин
  • 26.06.2023

Полиморфные отношения Ларавеля позволяют модели принадлежать более чем одной другой модели в одной ассоциации. Для этого урока мы возьмем официальный пример документации Laravel. Возьмем пример «комментариев» как в постах, так и в видео. Используя полиморфные связи, можно использовать одну таблицу комментариев для обоих этих сценариев.

По умолчанию Laravel будет использовать полное имя класса для хранения типа связанной модели.

Существует четыре типа полиморфных отношений в Laravel.

  1. One To One Polymorphic Relationship
  2. One To Many Polymorphic Relationship
  3. Many To Many Polymorphic Relationship
  4. Custom Polymorphic Relationship

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

один к одномуПолиморфное отношение «взаимно-однозначное» сравнимо с простым взаимно-однозначным отношением; Однако целевая модель может принадлежать нескольким типам моделей в одной ассоциации.

Например, запись блога и пользователь могут иметь полиморфное отношение к модели изображения.

Использование взаимно-однозначного полиморфного отношения позволяет получить единый список уникальных изображений, которые принимаются как для записей блога, так и для учетных записей пользователей.

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

«один ко многим»Полиморфное отношение «один ко многим» сравнимо с простым отношением «один ко многим»; Однако целевая модель может принадлежать нескольким типам моделей в одной ассоциации.

Например, представьте, что пользователи вашего приложения могут «комментировать» как публикации, так и видео.

Используя полиморфные отношения, вы можете использовать таблицу с одним комментарием для обоих этих вариантов использования.

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

«многие ко многим»Полиморфные отношения «многие-ко-многим» несколько сложнее, чем отношения morphOne и morphMulti.

Например, модель Blog Post и Video может иметь полиморфное отношение к модели Tag.

Используя полиморфное отношение «многие-ко-многим», у вас есть единый список уникальных тегов, общих для записей блога и видео.

Пользовательские полиморфные отношения

Например, учитывая приведенный выше пример «один ко многим», где комментарий может принадлежать публикации или видео, commentable_type по умолчанию будет App\Post или App\Video соответственно.

Тем не менее, вы можете позавидовать, если отделите свою базу данных от внутренней структуры вашего приложения.

В этом случае вы можете установить «карту морфов», чтобы указать Eloquent использовать пользовательское имя для каждой модели вместо имени класса.

Теперь давайте возьмем общий пример полиморфных отношений.

Всего есть три таблицы.

  1. posts
  2. videos
  3. comments

Причина, по которой мы можем применить здесь полиморфные отношения, заключается в том, что комментарии можно применять как к сообщениям, так и к видео.

Таким образом, модель комментариев может быть связана с постом и видео.

Теперь нам нужно добавить два дополнительных столбца в таблицу сообщений .

  1. commentable_id (Integer)
  2. commentable_type (String)

В столбце commentable_id будет указано значение идентификатора поста или видео.

Столбец commentable_type будет содержать имя класса модели-владельца. Теперь давайте начнем практику на примере полиморфных отношений Laravel.

Мы начинаем наш проект с установки проекта Laravel.

Шаг 1: Установите Laravel 6

Введите следующую команду в терминале.

laravel new relationships

# или

composer create-project laravel/laravel relationships --prefer-dist

После установки заходим в проект.

cd relationships

Откройте проект в редакторе кода.

code .

Настройте базу данных в файле .env .

Теперь создайте шаблон проверки подлинности с помощью следующей команды.

php artisan make:auth

Шаг 2: Создание моделей и миграция.

Перейдите в свой терминал и сначала создайте модель Post .

php artisan make:model Post -m

Кроме того, мы создаем видеомодель .

php artisan make:model Video -m

Теперь определите схему для обеих миграций. Но сначала давайте определим схему для create_posts_table.

// create_posts_table

public function up()
{
   Schema::create('posts', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->timestamps();
    });
}

Теперь определите схему для create_videos_table.

// create_videos_table

public function up()
{
     Schema::create('videos', function (Blueprint $table) {
         $table->increments('id');
         $table->string('name');            
         $table->timestamps();
     });
}

Хорошо, теперь мигрируйте с помощью следующей команды.

php artisan migrate

Шаг 3: Создайте два файла контроллера.

Хорошо, теперь мы создадим два контроллера для рендеринга представлений.

  1. PostController
  2. VideoController

Введите следующую команду, чтобы создать его.

php artisan make:controller PostController
php artisan make:controller VideoController

 Теперь напишите следующий код внутри файла PostController.php .

// PostController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Post;

class PostController extends Controller
{
    public function show(Post $post)
    {
        return view('post.show', compact('post'));
    }
}

То же самое и с файлом VideoController.php .

// VideoController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Video;

class VideoController extends Controller
{
    public function show(Video $video)
    {
        return view('video.show', compact('video'));
    }
}

Теперь создайте две папки внутри папки views .

  1. post
  2. video

Внутри папки post создайте новый файл с именем show.blade.php файл. Кроме того, то же самое создает тот же файл show.blade.php внутри папки с видео .

Шаг 4: Определите маршруты для показа поста и видео.

Внутри файла web.php напишите следующий код.

// web.php

Route::get('/post/{post}', 'PostController@show')->name('post.show');
Route::get('/video/{video}', 'VideoController@show')->name('video.show');

Теперь введите данные вручную в базу данных. В режиме реального времени данные поступают из формы, но для этой демонстрации сначала введите некоторые фиктивные данные в таблицу сообщений .

Laravel Polymorphic Relationship Tutorial ExampleТеперь вставьте данные в таблицу видео .

Polymorphic Relationship in Laravel

Итак, мы вставили фиктивные данные в обе таблицы.

Шаг 5: Закодируйте файлы просмотра.

Внутри post  >>  файле show.blade.php напишите следующий код.

<h3>{{ $post->name }}</h3>

Теперь перейдите в браузер и введите этот URL-адрес: http://relationships.test/post/1. Вы можете увидеть 1-й пост.

То же самое для видео  >>  show.blade.php напишите следующий код.

<h3>{{ $video->name }}</h3>

То же самое, зайдите в браузер и нажмите на этот URL-адрес: http://relationships.test/video/1. Вы можете посмотреть 1-е видео.

Шаг 6: Создайте модель комментариев.

Введите следующую команду, чтобы создать модель, а также выполнить миграцию.

php artisan make:model Comment -m

Теперь напишите следующую схему внутри create_comments_table.

// create_comments_table

public function up()
{
    Schema::create('comments', function (Blueprint $table) {
         $table->increments('id');
         $table->integer('user_id')->unsigned();
         $table->text('body');
         $table->integer('commentable_id')->unsigned();
         $table->string('commentable_type');
         $table->timestamps();
    });
}

Перенесите эту схему в базу данных.

php artisan migrate

Шаг 7: Определите отношения.

Теперь мы храним user_id внутри таблицы комментариев ; у нас есть отношения с Пользователем.

Комментарий принадлежит пользователю. Таким образом, мы можем записать эту связь внутри файла модели Comment.php.

 // Comment.php

public function user()
{
    return $this->belongsTo(User::class);
}

Хорошо, теперь мы пишем еще одну функцию внутри файла Comment.php , которая является commentable().

// Comment.php

public function commentable()
{
    return $this->morphTo();
}

Теперь это означает, что теперь одна или несколько моделей могут использовать эту модель комментариев. В нашем примере он может быть связан с постом и видео. Оба используют одну и ту же модель комментариев .

Итак, следующий шаг - модель поста имеет много комментариев. Таким образом, мы можем определить отношения внутри файла Post.php следующим образом.

// Post.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    public function comments()
    {
        return $this->morphMany(Comment::class, 'commentable');
    }
}

То же самое и с файлом Video.php .

 // Video.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Video extends Model
{
    public function comments()
    {
        return $this->morphMany(Comment::class, 'commentable');
    }
}

Шаг 8: Вставьте ручные данные в таблицу комментариев.

Мы наладили все отношения. Нам нужно ввести демонстрационные комментарии и посмотреть, получим ли мы комментарии на странице шоу видео и поста.

Polymorphic hasMany Relationship

Так, первый столбец – это id, как обычно, автоприращения, второй – user_id, который в данный момент подписан пользователем.

Третий столбец — commentable_id; в нашем случае это либо идентификатор таблицы сообщений , либо идентификатор таблицы видео .

Итак, мы прикрепили посты и таблицы видео к соответствующим комментариям.

Теперь визуализируйте сообщение с их комментариями в файле show.blade.php .

<h3>{{ $post->name }}</h3>

<ul>
    @foreach($post->comments as $comment)
    <li>{{ $comment->body }}</li>
    @endforeach
</ul>

Зайдите в браузер и нажмите на этот URL-адрес: http://relationships.test/post/1. Вы можете увидеть название сообщения и тело комментария. Вы можете написать тот же файл представления для видео  >>  show.blade.php.

 

<h3>{{ $video->name }}</h3>

<ul>
    @foreach($video->comments as $comment)
    <li>{{ $comment->body }}</li>
    @endforeach
</ul>

Теперь проверьте этот URL-адрес: http://relationships.test/video/1.

Вот и все; Мы успешно отобразили пост и видео с соответствующими комментариями.

Хотя в этом примере я вставил значения жесткого кода, но мы увидим программно в будущем.

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

Про мене

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

Об авторе CrazyBoy49z
WORK EXPERIENCE
Контакты
Ukraine, Lutsk
+380979856297