• Czas czytania ~8 min
  • 26.06.2023

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.

  1. One To One Polymorphic Relationship
  2. One To Many Polymorphic Relationship
  3. Many To Many Polymorphic Relationship
  4. 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.

  1. posts
  2. videos
  3. 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 .

  1. commentable_id (Integer)
  2. 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.

  1. PostController
  2. 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 .

  1. post
  2. 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 .

Laravel Polymorphic Relationship Tutorial ExampleTeraz wstaw dane do tabeli wideo .

Polymorphic Relationship in Laravel

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.

Polymorphic hasMany Relationship

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.

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

O

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...

O autorze CrazyBoy49z
WORK EXPERIENCE
Kontakt
Ukraine, Lutsk
+380979856297