Heim >Backend-Entwicklung >PHP-Tutorial >Wieder in die polymorphe Beziehungen von eloquentem Stellvertretern

Wieder in die polymorphe Beziehungen von eloquentem Stellvertretern

Lisa Kudrow
Lisa KudrowOriginal
2025-02-09 12:17:13590Durchsuche

Re-Introducing Eloquent's Polymorphic Relationships

Kernpunkte

    Die polymorphe Assoziation von
  • Laravel ermöglicht es einem Modell, zu mehreren anderen Modellen zu einer Assoziation zu gehören. Dies vereinfacht die Datenbankstruktur, erleichtert den Code einfacher und ermöglicht dynamischer und flexiblere Datenbeziehungen.
  • Aufstellen polymorpher Assoziationen in Laravel beinhaltet die Definition von Assoziationen im eloquenten Modell. Die morphTo -Methode wird verwendet, um ein polymorph -zugeordnetes Modell zu empfangen, während die morphMany oder morphOne -Methode an ein Modell verwendet wird, das mit anderen Modellen zugeordnet ist.
  • Die
  • Laravels MorphMap -Methode kann verwendet werden, um eloquent zu unterweisen, einen benutzerdefinierten Namen anstelle eines Klassennamens für jedes Modell zu verwenden. Dies ist hilfreich bei Modellnamensänderungen oder zu langer Namespaces.
  • Laravel unterstützt viele polymorphe Beziehungen mit vielen zu vielen zu vielen Modellen, sodass ein Modell zu mehreren Modellen auf vielen zu vielen Basis gehört. Dies ist besonders nützlich in komplexen Anwendungen.

Dieser Artikel wurde von Younes Rafie von Experten überprüft. Vielen Dank an alle Peer -Rezensenten von SitePoint, um den Inhalt von SitePoint perfekt zu machen!


Re-Introducing Eloquent's Polymorphic Relationships

Möglicherweise haben Sie verschiedene Arten von Beziehungen zwischen Modellen oder Datenbanktabellen verwendet, wie beispielsweise in Laravel: Eins-zu-Eins, Eins-zu-Many, viele zu viele und viele und haben Sie viel. Es gibt jedoch einen weiteren weniger häufigen Typ: polymorphe Assoziation. Was ist also eine polymorphe Assoziation?

Die polymorphe Assoziation

bezieht sich auf ein Modell, das zu mehreren anderen Modellen in einer Assoziation gehören kann.

Um dies zu veranschaulichen, erstellen wir eine fiktive Szene, in der wir Themen- und Postmodelle haben. Benutzer können Kommentare in Themen und Posts hinterlassen. Mit polymorphen Beziehungen können wir für beide Fälle eine einzelne Kommentarabelle verwenden. Überraschenderweise, oder? Dies scheint ein bisschen unpraktisch zu sein, da wir im Idealfall die Tabelle post_computers und die topic_comments -Tabelle erstellen müssen, um Kommentare zu unterscheiden. Mit polymorphen Beziehungen benötigen wir keine zwei Tabellen. Lassen Sie uns polymorphe Beziehungen durch ein praktisches Beispiel verstehen.

was wir bauen

Wir werden eine Demo -Musik -App erstellen, die Songs und Alben enthält. In dieser App können wir Songs und Alben mögen. Mit polymorphen Beziehungen verwenden wir für beide Fälle eine einzelne Upvotes -Tabelle. Lassen Sie uns zunächst die Tabellenstruktur untersuchen, die zum Aufbau dieser Beziehung erforderlich ist:

<code>albums
    id - integer
    name - string

songs
    id - integer
    title - string
    album_id - integer

upvotes
    id - integer
    upvoteable_id - integer
    upvoteable_type - string
</code>

Lassen Sie uns die Säulen upvoteable_id und upvoteable_type diskutieren, die für diejenigen, die zuvor noch keine polymorphen Beziehungen verwendet haben, ein wenig seltsam erscheinen. Die Spalte upvoteable_id enthält den ID -Wert des Albums oder des Songs, während die Spalte upvoteable_type den Klassennamen enthält, der das Modell besitzt. In der Spalte upvoteable_type bestimmt das ORM, welcher "Typ" beim Zugriff auf die upvoteable -Beziehung zurückkehren soll, um das Modell zu besitzen.

Modelle erzeugen und Migration

erzeugen

Ich gehe davon aus, dass Sie bereits eine laufende Laravel -Anwendung haben. Wenn nicht, kann dieser erweiterte Schnellstartkurs hilfreich sein. Erstellen wir zuerst drei Modelle und Migrationen und bearbeiten Sie dann die Migrationen, um unseren Anforderungen zu entsprechen.

<code>albums
    id - integer
    name - string

songs
    id - integer
    title - string
    album_id - integer

upvotes
    id - integer
    upvoteable_id - integer
    upvoteable_type - string
</code>

Beachten Sie, dass das Übergeben des -m -Flags beim Erstellen eines Modells auch Migrationen erzeugt, die diesen Modellen zugeordnet sind. Passen wir die up -Methoden in diesen Migrationen an, um die gewünschte Tabellenstruktur zu erhalten:

{some_timestamp}_create_albums_table.php

<code>php artisan make:model Album -m
php artisan make:model Song -m
php artisan make:model Upvote -m
</code>

{some_timestamp}_create_songs_table.php

<code class="language-php">public function up()
{
    Schema::create('albums', function (Blueprint $table) {
       $table->increments('id');
        $table->string('name');
        $table->timestamps();
    });
}</code>

{some_timestamp}_create_upvotes_table.php

<code class="language-php">public function up()
{
    Schema::create('songs', function (Blueprint $table) {
        $table->increments('id');
        $table->string('title');
        $table->integer('album_id')->unsigned()->index();
        $table->timestamps();

        $table->foreign('album_id')->references('id')->on('albums')->onDelete('cascade');
    });
}</code>

Jetzt können wir den Befehl handwerklich migrieren ausführen, um diese drei Tabellen zu erstellen:

<code class="language-php">public function up()
{
    Schema::create('upvotes', function (Blueprint $table) {
        $table->increments('id');
        $table->morphs('upvoteable'); // 添加无符号整数 upvoteable_id 和字符串 upvoteable_type
        $table->timestamps();
    });
}</code>

Konfigurieren wir unser Modell, um auf die polymorphe Beziehung zwischen Alben, Songs und Likes zu achten:

app/Upvote.php

<code>php artisan migrate</code>

app/Album.php

<code class="language-php">[...]
class Upvote extends Model
{
    /**
     * 获取所有拥有模型。
     */
    public function upvoteable()
    {
        return $this->morphTo();
    }
}</code>

app/Song.php

<code class="language-php">class Album extends Model
{
    protected $fillable = ['name'];

    public function songs()
    {
        return $this->hasMany(Song::class);
    }

    public function upvotes()
    {
        return $this->morphMany(Upvote::class, 'upvoteable');
    }
}</code>
Die

-Methode in den upvotes -Album- und Songmodellen definiert die polymorphe Eins-zu-Viele-Beziehung zwischen diesen Modellen und dem Upvote-Modell und hilft uns, alle Leuten wie diese bestimmte Modellinstanz zu erhalten.

Nachdem wir die Beziehung definiert haben, können wir jetzt die Anwendung versuchen, um besser zu verstehen, wie polymorphe Beziehungen funktionieren. Wir werden keine Ansichten für diese App erstellen, wir werden unsere App nur aus der Konsole probieren.

Wenn Sie den Controller berücksichtigen und wo wir die gleiche Methode platzieren sollten, empfehle ich, einen AlbumUpVoteController und einen SongUpVoteController zu erstellen. Auf diese Weise können wir, wenn wir uns mit polymorphen Beziehungen befassen, die Dinge strikt mit dem Objekt verbinden, auf dem wir arbeiten. In unserem Fall können wir das Album und Lied mögen. Likes sind kein Album oder ein Lied. Außerdem ist es kein General wie, was das Gegenteil davon ist, wie wir in den meisten Eins-zu-Viele-Beziehungen upvotesController haben. Hoffe das macht Sinn.

Beginnen wir die Konsole:

<code class="language-php">class Song extends Model
{
    protected $fillable = ['title', 'album_id'];

    public function album()
    {
        return $this->belongsTo(Album::class);
    }

    public function upvotes()
    {
        return $this->morphMany(Upvote::class, 'upvoteable');
    }
}</code>

Abrufbeziehung

Jetzt, da wir einige Daten bereit haben, können wir über unser Modell auf unsere Beziehungen zugreifen. Hier ist ein Screenshot der Daten in der Upvotes -Tabelle:

Re-Introducing Eloquent's Polymorphic Relationships

Um auf alle wie das Album zuzugreifen, können wir upvotes dynamisches Attribut verwenden:

<code>php artisan tinker
>>> $album = App\Album::create(['name' => 'More Life']);
>>> $song = App\Song::create(['title' => 'Free smoke', 'album_id' => 1]);
>>> $upvote1 = new App\Upvote;
>>> $upvote2 = new App\Upvote;
>>> $upvote3 = new App\Upvote;
>>> $album->upvotes()->save($upvote1);
>>> $song->upvotes()->save($upvote2);
>>> $album->upvotes()->save($upvote3);</code>

kann auch den Eigentümer einer polymorphen Beziehung aus dem polymorphen Modell abrufen, indem er auf den Namen der Methode zugreift, die den Aufruf nach morphTo ausführt. In unserem Fall ist das die upvoteable -Methode auf dem Upvote -Modell. Daher werden wir als dynamische Eigenschaft auf die Methode zugreifen:

<code class="language-php">$album = App\Album::find(1);
$upvotes = $album->upvotes;
$upvotescount = $album->upvotes->count();</code>
Die

-Relation zum upvoteable upvote -Modell wird eine Albuminstanz zurückgeben, da dies wie die Instanz der Albuminstanz gehört.

Da wir die Anzahl der Likes für einen Song oder ein Album erhalten können, können wir den Song oder Album basierend auf Likes auf der Ansicht sortieren. So funktionieren Musikdiagramme.

Für Songs werden wir wie folgt wie folgt:

<code>albums
    id - integer
    name - string

songs
    id - integer
    title - string
    album_id - integer

upvotes
    id - integer
    upvoteable_id - integer
    upvoteable_type - string
</code>

benutzerdefinierte polymorphe Typ

standardmäßig verwendet Laravel vollständig qualifizierte Klassennamen, um die Arten des relevanten Modells zu speichern. Zum Beispiel ist Upvote im obigen Beispiel zu Album oder Song, und der Standard upvoteable_type ist App\Album bzw. App\Song.

Dies hat jedoch einen großen Nachteil. Was ist, wenn sich der Namespace des Albummodells ändert? Wir müssen eine Art Migration durchführen, um alle Ereignisse in der Upvotes -Tabelle umzubenennen. Das ist ein bisschen schwierig! Was passiert, wenn der Namespace lang ist (z. B. App\Models\Data\Topics\Something\SomethingElse)? Dies bedeutet, dass wir eine sehr lange maximale Länge auf der Spalte einstellen müssen. Hier kann uns die MorphMap -Methode helfen.

Die "MorphMap" -Methode unterrichtet eloquent, einen benutzerdefinierten Namen für jedes Modell zu verwenden, nicht für den Klassennamen:

<code>php artisan make:model Album -m
php artisan make:model Song -m
php artisan make:model Upvote -m
</code>

Wir können MorphMap in der Startfunktion des AppServiceProviders registrieren oder einen separaten Dienstanbieter erstellen. Damit die neuen Änderungen wirksam werden können, müssen wir den Befehl componist Dump-autoload ausführen. Jetzt können wir diesen neuen Aufzeichnungen hinzufügen:

<code class="language-php">public function up()
{
    Schema::create('albums', function (Blueprint $table) {
       $table->increments('id');
        $table->string('name');
        $table->timestamps();
    });
}</code>

es verhält sich genauso wie das vorherige Beispiel.

Schlussfolgerung

Auch wenn Sie möglicherweise noch nie auf eine Situation gestoßen sind, in der Sie polymorphe Beziehungen verwenden müssen, kann dieser Tag irgendwann kommen. Der Vorteil der Verwendung von Laravel besteht darin, dass der Umgang mit dieser Situation sehr einfach ist und keine Modell -Assoziations -Tricks erforderlich ist, um die Dinge zum Laufen zu bringen. Laravel unterstützt sogar viele zu viele polymorphe Beziehungen. Hier können Sie mehr darüber lesen.

Ich hoffe, Sie haben jetzt polymorphe Beziehungen verstanden und was für diese Art von Beziehungen erforderlich sein kann. Ein weiteres etwas fortgeschritteneres Beispiel für polymorphe Beziehungen ist hier. Wenn Sie dies hilfreich finden, teilen Sie es bitte mit Ihren Freunden und vergessen Sie nicht, auf die Schaltfläche "Gefällt mir" zu klicken. Fühlen Sie sich frei, Ihre Gedanken im Kommentarbereich unten zu lassen!

FAQs über eloquent polymorphe Beziehungen

Was sind die Vorteile der Verwendung polymorpher Beziehungen in Laravel?

polymorphe Beziehungen in Laravel bieten eine flexible und effiziente Möglichkeit, verwandte Daten zwischen verschiedenen Modellen zu verarbeiten. Sie ermöglichen es einem Modell, zu mehreren anderen Modellenarten in einer Assoziation zu gehören. Dies bedeutet, dass Sie unabhängig von ihrem Typ eine einzigartige Liste der eindeutigen Kennung aller relevanten Daten haben können. Dies kann Ihre Datenbankstruktur erheblich vereinfachen und Ihren Code erleichtern. Es ermöglicht auch dynamischere und flexiblere Datenbeziehungen, die in komplexen Anwendungen besonders nützlich sind.

Wie kann man polymorphe Beziehungen in Laravel einstellen?

Aufstellen polymorpher Beziehungen in Laravel beinhaltet die Definition von Beziehungen im beredten Modell. Zunächst müssen Sie die Beziehung zum Modell definieren, die die polymorphe Beziehung erhalten. Dies geschieht mit der morphTo -Methode. Verwenden Sie dann auf dem Modell, das den anderen Modellen zugeordnet ist, die Methode morphMany oder morphOne entsprechend, ob die Beziehung eins zu vielen oder eins zu eins ist.

Können Sie ein Beispiel für polymorphe Beziehungen in Laravel angeben?

Betrachten wir natürlich eine Blog -Plattform, auf der sowohl Beiträge als auch Benutzer Kommentare erhalten können. In diesem Fall wird das Kommentarmodell eine polymorphe Beziehung zu den Post- und Benutzermodellen haben. Hier erfahren Sie, wie Sie diese Beziehung definieren können:

<code>albums
    id - integer
    name - string

songs
    id - integer
    title - string
    album_id - integer

upvotes
    id - integer
    upvoteable_id - integer
    upvoteable_type - string
</code>

Wie kann man polymorphe Beziehungen verwenden, um verwandte Datensätze abzurufen?

Sie können relevante Datensätze in polymorphen Beziehungen abrufen, wie Sie es mit jeder anderen beredten Beziehung tun würden. Wenn Sie beispielsweise alle Kommentare aus einem Beitrag abrufen möchten, können Sie dies tun:

<code>php artisan make:model Album -m
php artisan make:model Song -m
php artisan make:model Upvote -m
</code>

Wie speichern Sie verwandte Datensätze mithilfe polymorpher Beziehungen?

verwandte Datensätze in polymorphen Beziehungen auch ähnlich wie andere beredte Beziehungen. Sie können das Modell mit der associate -Methode assoziieren und das Modell speichern. Hier ist ein Beispiel:

<code class="language-php">public function up()
{
    Schema::create('albums', function (Blueprint $table) {
       $table->increments('id');
        $table->string('name');
        $table->timestamps();
    });
}</code>

Was sind einige häufige Anwendungsfälle für polymorphe Beziehungen?

polymorphe Beziehungen sind besonders nützlich in Situationen, in denen das Modell zu mehreren anderen Arten von Modellen gehören kann. Einige gemeinsame Anwendungsfälle enthalten Kommentare, die zu Posts und Benutzern angehören können, Tags, die auf mehrere Arten von Inhalten angewendet werden können, sowie Bilder oder Dateien, die an verschiedene Arten von Entitäten angehängt werden können.

Was sind die Einschränkungen oder Nachteile der Verwendung polymorpher Beziehungen?

Während polymorphe Beziehungen viel Flexibilität bieten, sind sie möglicherweise auch komplexer und schwieriger zu errichten und zu verwalten als die eloquenten Standardbeziehungen. Sie unterstützen auch alle Merkmale von Standardbeziehungen, z. B. den Wunsch nach Belastungsbeschränkungen.

Wie löscht ich relevante Datensätze in polymorphen Beziehungen?

Sie können die Methode delete für die Beziehung verwenden, um relevante Datensätze in einer polymorphen Beziehung zu löschen. Um beispielsweise alle Kommentare aus einem Beitrag zu löschen, können Sie dies tun:

<code class="language-php">public function up()
{
    Schema::create('songs', function (Blueprint $table) {
        $table->increments('id');
        $table->string('title');
        $table->integer('album_id')->unsigned()->index();
        $table->timestamps();

        $table->foreign('album_id')->references('id')->on('albums')->onDelete('cascade');
    });
}</code>

Kann ich polymorphe Beziehungen zu vielen zu vielen Beziehungen verwenden?

Ja, Laravel unterstützt viele polymorphe Beziehungen durch die morphToMany und morphedByMany Methoden. Auf diese Weise kann ein Modell mehrfach zu mehreren Modellen gehören.

Wie kann man mit polymorphen Beziehungen in der Datenbankmigration umgehen?

In einer Datenbankmigration fügen Sie der Tabelle normalerweise zwei Spalten hinzu, die polymorphe Beziehungen empfangen: eine für die zugehörige Modell -ID und die andere für den zugehörigen Modelltyp. Laravel bietet eine bequeme morphs -Methode zum Hinzufügen dieser Spalten:

<code class="language-php">public function up()
{
    Schema::create('upvotes', function (Blueprint $table) {
        $table->increments('id');
        $table->morphs('upvoteable'); // 添加无符号整数 upvoteable_id 和字符串 upvoteable_type
        $table->timestamps();
    });
}</code>

Dies fügt der Tabelle commentable_id und commentable_type Spalten hinzu.

Das obige ist der detaillierte Inhalt vonWieder in die polymorphe Beziehungen von eloquentem Stellvertretern. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn