Поліморфний зв'язок Ларавеля дозволяє моделі належати до більш ніж однієї іншої моделі на одній асоціації. Ми візьмемо офіційний приклад документації Laravel для цього підручника. Візьмемо приклад «коментарів» як у публікаціях, так і у відео. Використовуючи поліморфні зв'язки, можна використовувати одну таблицю приміток для обох цих сценаріїв.
За замовчуванням Laravel використовуватиме повне ім'я класу для зберігання типу пов'язаної моделі.
У Ларавелі існує чотири типи поліморфних відносин.
- One To One Polymorphic Relationship
- One To Many Polymorphic Relationship
- Many To Many Polymorphic Relationship
- Custom Polymorphic Relationship
Поліморфний зв'язок
один до одногоПоліморфний зв'язок один-до-одного можна порівняти з простим відношенням один-до-одного; Однак цільова модель може належати до більш ніж одного типу моделі на одній асоціації.
Наприклад, публікація блогу та користувач можуть мати поліморфне відношення до моделі зображення.
Використання поліморфного відношення один до одного дозволяє мати єдиний список унікальних зображень, які приймаються як для записів блогу, так і для облікових записів користувачів.
Один до багатьох поліморфних зв'язків
Поліморфний зв'язок один-до-багатьох можна порівняти з простим відношенням один-до-багатьох; Однак цільова модель може належати до більш ніж одного типу моделі на одній асоціації.
Наприклад, уявіть, що користувачі вашого додатка можуть "коментувати" як публікації, так і відео.
Використовуючи поліморфні зв'язки, ви можете використовувати таблицю окремих коментарів для обох цих випадків використання.
Багато поліморфних відносин
Поліморфні відносини багато-до-багатьох дещо складніші, ніж морфОдин і морфБагато відносин.
Наприклад, модель публікації в блозі та відео може мати поліморфне відношення до моделі тегів.
Використовуючи поліморфне відношення багато-до-багатьох, ви отримаєте єдиний список унікальних тегів, спільних для записів блогу та відео.
Настроюваний поліморфний зв'язок
Наприклад, враховуючи наведений вище приклад «один-до-багатьох», де коментар може належати до допису або відео, commentable_type за замовчуванням буде «App\Post» або «App\Video» відповідно.
Однак ви можете позаздрити відокремити вашу базу даних від внутрішньої структури вашої програми.
У цьому випадку ви можете встановити "карту морфінгу", щоб наказати Eloquent використовувати власне ім'я для кожної моделі замість імені класу.
Тепер давайте розглянемо загальний приклад поліморфного зв'язку.
Всього є три таблиці.
- posts
- videos
- comments
Тепер причина, по якій ми можемо застосувати поліморфний зв'язок тут, полягає в тому, що коментар можна застосовувати як до публікацій, так і до відео.
Так, модель Comment може бути пов'язана з Post і Video.
Тепер нам потрібно додати два додаткові стовпці всередині таблиці публікацій .
- commentable_id (Integer)
- commentable_type (String)
Стовпець commentable_id міститиме ідентифікаційне значення публікації або відео.
Стовпець commentable_type міститиме ім'я класу моделі, що володіє. Тепер давайте почнемо практику на прикладі поліморфних відносин Ларавела.
Ми починаємо наш проект з установки проекту 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: Створіть два файли контролера.
Гаразд, тепер ми створимо два контролери для відображення представлень.
- PostController
- 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'));
}
}
Тепер створіть дві папки всередині папки «Подання ».
- post
- video
Усередині папки запису створіть новий файл, який називається файлом 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');
Тепер введіть дані вручну в базу даних. У режимі реального часу дані надходять з форми, але для цієї демонстрації, по-перше, введіть деякі фіктивні дані в таблицю публікацій .
Тепер вставте дані в таблицю відео .
Отже, ми вставили фіктивні дані в обидві таблиці.
Крок 5: Закодуйте файли перегляду.
Всередині повідомлення >> файлі 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: Вставте дані вручну в таблицю коментарів.
Ми налагодили всі відносини. Нам потрібно ввести демонстраційні коментарі та подивитися, чи отримаємо ми коментарі на сторінці шоу відео та публікації.
Так, перший стовпець 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.
Ось і все; Ми успішно відобразили публікацію та відео з відповідними коментарями.
Хоча, в цьому прикладі, я вставив значення жорсткого коду, але ми побачимо програмно в майбутньому.