Laravel Polymorphic Relationship pozwala modelowi należeć do więcej niż jednego innego modelu w jednym powiązaniu. Weźmiemy oficjalny przykład dokumentacji Laravel dla tego samouczka. Weźmy przykład "komentarza" zarówno w postach, jak i filmach. Korzystając z relacji polimorficznych, można użyć pojedynczej tabeli komentarzy dla obu tych scenariuszy.
Domyślnie Laravel użyje w pełni kwalifikowanej nazwy klasy do przechowywania typu powiązanego modelu.
W Laravel istnieją cztery typy relacji polimorficznych.
- One To One Polymorphic Relationship
- One To Many Polymorphic Relationship
- Many To Many Polymorphic Relationship
- Custom Polymorphic Relationship
Relacja
polimorficzna jeden do jednegoRelacja polimorficzna jeden-do-jednego jest porównywalna do prostej relacji jeden-do-jednego; Jednak model docelowy może należeć do więcej niż jednego typu modelu w jednym skojarzeniu.
Na przykład wpis na blogu i użytkownik mogą współdzielić polimorficzną relację z modelem obrazu.
Użycie relacji polimorficznej jeden-do-jednego umożliwia utworzenie jednej listy unikatowych obrazów, które są akceptowane zarówno dla wpisów w blogu, jak i kont użytkowników.
Relacja
polimorficzna jeden do wieluRelacja polimorficzna jeden-do-wielu jest porównywalna z prostą relacją jeden-do-wielu; Jednak model docelowy może należeć do więcej niż jednego typu modelu w jednym skojarzeniu.
Załóżmy na przykład, że użytkownicy Twojej aplikacji mogą "komentować" zarówno posty, jak i filmy.
Korzystając z relacji polimorficznych, można użyć pojedynczej tabeli komentarzy dla obu tych przypadków użycia.
Wiele do wielu Zależność
polimorficznaRelacje polimorficzne wiele-do-wielu są nieco bardziej skomplikowane niż relacje morphOne i morphWiele.
Na przykład model posta na blogu i filmu może współdzielić polimorficzną relację z modelem tagu.
Korzystając z relacji polimorficznych wiele-do-wielu, masz jedną listę unikatowych tagów udostępnianych we wpisach na blogu i w filmach.
Niestandardowa relacja
polimorficznaNa przykład, biorąc pod uwagę powyższy przykład jeden-do-wielu, w którym komentarz może należeć do posta lub filmu, domyślnym commentable_type będzie odpowiednio App\Post lub App\Video.
Możesz jednak zazdrościć oddzielenia bazy danych od wewnętrznej struktury aplikacji.
W takim przypadku możesz ustawić "mapę morfową", aby poinstruować Eloquent, aby używał niestandardowej nazwy dla każdego modelu zamiast nazwy klasy.
Weźmy teraz ogólny przykład relacji polimorficznej.
Istnieją w sumie trzy stoły.
- posts
- videos
- comments
Powodem, dla którego możemy zastosować tutaj relację polimorficzną jest to, że komentarz można zastosować zarówno do postów, jak i filmów.
Tak więc model komentarzy może być powiązany z postem i wideo.
Teraz musimy dodać dwie dodatkowe kolumny w tabeli postów .
- commentable_id (Integer)
- commentable_type (String)
Kolumna commentable_id będzie zawierać wartość identyfikatora posta lub filmu.
Kolumna commentable_type będzie zawierać nazwę klasy modelu właścicielskiego. Zacznijmy teraz ćwiczyć na przykładzie relacji polimorficznych Laravel.
Nasz projekt rozpoczynamy od zainstalowania projektu Laravel.
Krok 1: Zainstaluj Laravel 6
Wpisz następujące polecenie w terminalu.
laravel new relationships
# lub
composer create-project laravel/laravel relationships --prefer-dist
Po instalacji przejdź do projektu.
cd relationships
Otwórz projekt w edytorze kodu.
code .
Skonfiguruj bazę danych w pliku env .
Teraz utwórz rusztowanie uwierzytelniania za pomocą następującego polecenia.
php artisan make:auth
Krok 2: Tworzenie modeli i migracji.
Przejdź do terminala i najpierw utwórz model Post .
php artisan make:model Post -m
Ponadto tworzymy model wideo .
php artisan make:model Video -m
Teraz zdefiniuj schemat dla obu migracji. Ale najpierw zdefiniujmy schemat dla create_posts_table.
// create_posts_table
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
Teraz zdefiniuj schemat dla create_videos_table.
// create_videos_table
public function up()
{
Schema::create('videos', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
Dobrze, teraz migruj za pomocą następującego polecenia.
php artisan migrate
Krok 3: Utwórz dwa pliki kontrolera.
Okay, teraz utworzymy dwa kontrolery do renderowania widoków.
- PostController
- VideoController
Wpisz następujące polecenie, aby je wygenerować.
php artisan make:controller PostController
php artisan make:controller VideoController
Teraz napisz następujący kod w pliku 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'));
}
}
To samo dotyczy pliku 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'));
}
}
Teraz utwórz dwa foldery w folderze widoków .
- post
- video
W folderze postów utwórz nowy plik o nazwie show.blade.php . Ponadto ten sam tworzy ten sam plik show.blade.php w folderze wideo .
Krok 4: Zdefiniuj trasy, aby wyświetlić post i wideo.
Wewnątrz pliku web.php napisz następujący kod.
// web.php
Route::get('/post/{post}', 'PostController@show')->name('post.show');
Route::get('/video/{video}', 'VideoController@show')->name('video.show');
Teraz wprowadź dane ręcznie do bazy danych. W czasie rzeczywistym dane pochodzą z formularza, ale w tym pokazie najpierw wprowadź dane fikcyjne w tabeli postów .
Teraz wstaw dane do tabeli wideo .
Tak więc wstawiliśmy fikcyjne dane w obu tabelach.
Krok 5: Zakoduj pliki widoku.
Wewnątrz postu >> pliku show.blade.php wpisz następujący kod.
<h3>{{ $post->name }}</h3>
Teraz przejdź do przeglądarki i wpisz ten adres URL: http://relationships.test/post/1. Możesz zobaczyć 1. post.
To samo dotyczy pliku wideo >> show.blade.php napisz następujący kod.
<h3>{{ $video->name }}</h3>
To samo, przejdź do przeglądarki i kliknij ten adres URL: http://relationships.test/video/1. Możesz zobaczyć 1. film.
Krok 6: Utwórz model komentarza.
Wpisz następujące polecenie, aby wygenerować model oraz migrację.
php artisan make:model Comment -m
Teraz napisz następujący schemat wewnątrz 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();
});
}
Przeprowadź migrację tego schematu do bazy danych.
php artisan migrate
Krok 7: Zdefiniuj relacje.
Teraz przechowujemy user_id w tabeli komentarzy ; mamy relację z Użytkownikiem.
Komentarz jest użytkownikiem należącym do użytkownika. Możemy więc zapisać tę relację w pliku modelu Comment.php.
// Comment.php
public function user()
{
return $this->belongsTo(User::class);
}
Dobra, teraz piszemy jeszcze jedną funkcję wewnątrz pliku Comment.php , która jest commentable().
// Comment.php
public function commentable()
{
return $this->morphTo();
}
Oznacza to, że teraz jeden lub więcej modeli może korzystać z tego modelu komentarza. W naszym przykładzie może być powiązany z postem i filmem. Oba używają tego samego modelu komentarza .
Okej, więc następnym krokiem jest to, że model postu ma wiele komentarzy. Możemy więc zdefiniować relację wewnątrz pliku Post.php w ten sposób.
// Post.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
}
To samo dotyczy pliku 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');
}
}
Krok 8: Wstaw dane ręczne do tabeli komentarzy.
Ustaliliśmy wszystkie relacje. Musimy wprowadzić komentarze demonstracyjne i sprawdzić, czy otrzymamy komentarze na stronie pokazu wideo i postu.
Tak więc pierwsza kolumna to id, jak zwykle, automatyczne przyrosty, druga to user_id, która jest obecnie podpisanym użytkownikiem.
Trzecia kolumna to commentable_id; w naszym przypadku jest to identyfikator tabeli postów lub identyfikator tabeli wideo .
Dlatego dołączyliśmy posty i tabele wideo do ich odpowiednich komentarzy.
Teraz wyrenderuj post z komentarzami w pliku show.blade.php .
<h3>{{ $post->name }}</h3>
<ul>
@foreach($post->comments as $comment)
<li>{{ $comment->body }}</li>
@endforeach
</ul>
Przejdź do przeglądarki i kliknij ten adres URL: http://relationships.test/post/1. Możesz zobaczyć nazwę posta i treść komentarza. Możesz zapisać ten sam plik widoku dla >> wideo show.blade.php.
<h3>{{ $video->name }}</h3>
<ul>
@foreach($video->comments as $comment)
<li>{{ $comment->body }}</li>
@endforeach
</ul>
Teraz przetestuj ten adres URL: http://relationships.test/video/1.
To wszystko; Z powodzeniem wyświetliliśmy post i wideo z ich odpowiednimi komentarzami.
Chociaż w tym przykładzie wstawiłem wartości hardcode, ale zobaczymy programowo w przyszłości.