Heim >Backend-Entwicklung >PHP-Tutorial >Wieder in die polymorphe Beziehungen von eloquentem Stellvertretern
Kernpunkte
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. 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. 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!
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 Assoziationbezieht 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.
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.
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>
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:
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>
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.
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!
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.
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.
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>
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>
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>
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.
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.
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>
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.
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!