Modellverein
Eloquent: Assoziation
- Einführung
- Assoziation definieren
- Polymorphe Assoziation
- Abfragezuordnung
- Vorladen
- Einfügen & Zugehöriges Modell aktualisieren
- Übergeordneten Satz-Zeitstempel aktualisieren
Einführung
Datenbanktabellen stehen normalerweise in Beziehung zueinander. Beispielsweise kann ein Blog-Beitrag viele Kommentare enthalten oder eine Bestellung kann einem Benutzer entsprechen, der die Bestellung aufgegeben hat. Beredt Vereinfacht die Verwaltung und Nutzung dieser Zuordnungen und unterstützt mehrere Arten von Zuordnungen:
Assoziationen definieren
Eloquente Assoziationen werden als Methoden in Eloquent-Modellklassen dargestellt. Wie das Eloquent-Modell selbst können Assoziationen auch als leistungsstarker Builder für Abfrageanweisungen verwendet werden und leistungsstarke Kettenaufrufe und Abfragefunktionen bereitstellen. Beispielsweise können wir eine Einschränkung an den verketteten Aufruf der posts
-Assoziation anhängen:
$user->posts()->where('active', 1)->get();
Aber bevor wir uns mit der Verwendung von Assoziationen befassen, lernen wir, wie man jeden Assoziationstyp definiert.
Eins-zu-eins
Eins-zu-eins ist die grundlegendste Beziehung. Beispielsweise könnte ein User
-Modell mit einem Phone
-Modell verknüpft sein. Um diese Assoziation zu definieren, müssen wir eine User
-Methode im phone
-Modell schreiben. Rufen Sie die phone
-Methode innerhalb der hasOne
-Methode auf und geben Sie ihr Ergebnis zurück:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model{ /** * Get the phone record associated with the user. */ public function phone() { return $this->hasOne('App\Phone'); } }
hasOne
Der erste Parameter der Methode ist der Klassenname des zugehörigen Modells. Sobald die Modellzuordnung definiert ist, können wir die dynamischen Eigenschaften von Eloquent verwenden, um die zugehörigen Datensätze abzurufen. Dynamische Eigenschaften ermöglichen Ihnen den Zugriff auf relationale Methoden genau wie im Modell definierte Eigenschaften:
$phone = User::find(1)->phone;
Eloquent ermittelt den Fremdschlüsselnamen basierend auf dem Modellnamen. In diesem Fall wird automatisch davon ausgegangen, dass das Phone
-Modell einen user_id
-Fremdschlüssel hat. Wenn Sie diese Konvention außer Kraft setzen möchten, können Sie einen zweiten Parameter an die hasOne
-Methode übergeben:
return $this->hasOne('App\Phone', 'foreign_key');
Darüber hinaus geht Eloquent davon aus, dass der Wert des Fremdschlüssels gleich dem Wert der übergeordneten ID ist (bzw benutzerdefinierter $primaryKey)-Spaltenabgleich. Mit anderen Worten: Eloquent sucht in der Spalte „user_id“ des Telefondatensatzes nach einem Wert, der mit der Spalte „id“ der Tabelle „Benutzer“ übereinstimmt. Wenn Sie möchten, dass die Zuordnung einen anderen benutzerdefinierten Schlüsselnamen als id verwendet, können Sie den dritten Parameter an die hasOne-Methode übergeben:
return $this->hasOne('App\Phone', 'foreign_key', 'local_key');
Definieren Sie die umgekehrte Zuordnung
Wir Auf das User
-Modell kann bereits über das Phone
-Modell zugegriffen werden. Definieren wir nun eine weitere Zuordnung für das Modell Phone
, die uns Zugriff auf das Modell User
gewährt, dem das Telefon gehört. Wir können eine umgekehrte Assoziation mithilfe der hasOne
-Methode definieren, die der belongsTo
-Methode entspricht:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Phone extends Model{ /** * 获得拥有此电话的用户 */ public function user() { return $this->belongsTo('App\User'); } }
Im obigen Beispiel versucht Eloquent, Phone
mit user_id
im User
-Modell abzugleichen id
am Modell. Der Standard-Fremdschlüsselname wird ermittelt, indem der Name der Beziehungsmethode überprüft und _id
als Suffixname verwendet wird. Wenn der Fremdschlüssel des Phone
-Modells jedoch nicht user_id
ist, kann ein benutzerdefinierter Schlüsselname als zweiter Parameter an die belongsTo
-Methode übergeben werden:
/** * 获得拥有此电话的用户 */ public function user(){ return $this->belongsTo('App\User', 'foreign_key'); }
Wenn dies beim übergeordneten Modell nicht der Fall ist verwenden id
Als Primärschlüssel oder wenn Sie verschiedene Felder zum Verbinden untergeordneter Modelle verwenden möchten, können Sie belongsTo
übergeben Die Methode übergibt den dritten Parameter in Form der Angabe des benutzerdefinierten Schlüssels der übergeordneten Datentabelle:
/** * 获得拥有此电话的用户 */ public function user(){ return $this->belongsTo('App\User', 'foreign_key', 'other_key'); }
Eins-zu-viele
„Eins-zu-viele“-Assoziation wird verwendet, um ein einzelnes Modell so zu definieren, dass es eine beliebige Anzahl anderer verknüpfter Modelle hat. Beispielsweise kann ein Blog-Beitrag unendlich viele Kommentare enthalten. Wie alle anderen Eloquent-Beziehungen wird eine Eins-zu-Viele-Beziehung durch Schreiben einer Methode im Eloquent-Modell definiert:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Post extends Model{ /** * 获取博客文章的评论 */ public function comments() { return $this->hasMany('App\Comment'); } }
Denken Sie daran, dass Eloquent automatisch das Fremdschlüsselattribut des Comment
-Modells bestimmt. Konventionell verwendet Eloquent die „Snake Case“-Form des Modellnamens sowie das Suffix _id
als Fremdschlüsselfeld. Daher geht Eloquent im obigen Beispiel davon aus, dass der Fremdschlüssel des Modells, der Comment
entspricht, Post
ist. post_id
-Attribut des Modells abgerufen werden. Denken Sie daran: Da Eloquent „dynamische Eigenschaften“ bereitstellt, können wir auf die Beziehungsmethode genauso zugreifen wie auf die Eigenschaften des Modells: Post
$comments = App\Post::find(1)->comments;foreach ($comments as $comment) { //}
comments
Da natürlich alle Beziehungen auch als Builder für Abfrageanweisungen verwendet werden können, können Sie verkettete Aufrufe verwenden um der -Methode zusätzliche Einschränkungen hinzuzufügen: $comment = App\Post::find(1)->comments()->where('title', 'foo')->first();
comments
Genau wie die -Methode können Sie auch verwenden -Methode überschreiben Sie die Standardfremdschlüssel und lokalen Schlüssel, indem Sie zusätzliche Parameter übergeben: hasOne
return $this->hasMany('App\Comment', 'foreign_key'); return $this->hasMany('App\Comment', 'foreign_key', 'local_key');
hasMany
Jetzt können wir alle Kommentare eines Artikels abrufen und dann eine Zuordnung definieren, um den Artikel über die Kommentare zu erhalten. Diese Assoziation ist die umgekehrte Assoziation der
-Assoziation. Sie muss mit der-Methode im untergeordneten Modell definiert werden: hasMany
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Comment extends Model{ /** * 获取此评论所属文章 */ public function post() { return $this->belongsTo('App\Post'); } }
belongsTo
Nachdem diese Beziehung definiert ist, können wir auf die -Modelle zugreifen Verwenden Sie dieses „dynamische Attribut“, um das zugehörige Comment
abzurufen Modelliert: post
$comment = App\Comment::find(1); echo $comment->post->title;
Post
Im obigen Beispiel versucht Eloquent, das des -Modells mit dem Comment
des post_id
-Modells abzugleichen. Der Standard-Fremdschlüsselname wird von Eloquent anhand des Assoziationsnamens bestimmt, gefolgt von _ und dem Primärschlüsselfeldnamen als Suffix. Wenn der Fremdschlüssel des Post
-Modells natürlich nicht id
ist, können Sie den benutzerdefinierten Schlüsselnamen als zweiten Parameter an die Comment
-Methode übergeben: post_id
/** * 获取此评论所属文章 */ public function post(){ return $this->belongsTo('App\Post', 'foreign_key'); }
belongsTo
Wenn dies beim übergeordneten Modell nicht der Fall ist verwenden Als Primärschlüssel oder wenn Sie verschiedene Felder zum Verbinden untergeordneter Modelle verwenden möchten, können Sie übergeben Die Methode übergibt den dritten Parameter in Form der Angabe des benutzerdefinierten Schlüssels der übergeordneten Datentabelle: id
/** * 获取此评论所属文章 */ public function post(){ return $this->belongsTo('App\Post', 'foreign_key', 'other_key'); }
belongsTo
Viele-zu-viele
Viele-zu-viele-Beziehungen sind etwas komplexer als hasOne
- und hasMany
-Beziehungen. Beispielsweise kann ein Benutzer viele Rollen haben und diese Rollen werden von anderen Benutzern geteilt. Beispielsweise könnten viele Benutzer die Rolle „Administrator“ haben. Um diese Zuordnung zu definieren, sind drei Datenbanktabellen erforderlich: users
, roles
und role_user
. Die role_user
-Tabelle ist in alphabetischer Reihenfolge nach den beiden zugehörigen Modellen benannt und enthält die Felder user_id
und role_id
.
Many-to-many-Assoziation wird durch Aufrufen des von der internen Methode belongsToMany
zurückgegebenen Ergebnisses definiert. Beispielsweise definieren wir die Methode User
im Modell roles
:
<?php namespace App; use Illuminate\Database\Eloquent\Model;class User extends Model{ /** * 用户拥有的角色 */ public function roles() { return $this->belongsToMany('App\Role'); } }
Sobald die Zuordnung definiert ist, können Sie roles
übergeben Dynamische Attribute erhalten Benutzerrollen:
$user = App\User::find(1); foreach ($user->roles as $role) { // }
Natürlich können Sie wie bei allen anderen Assoziationsmodellen die Methode roles
verwenden, um der Abfrageanweisung mithilfe von Kettenaufrufen Einschränkungen hinzuzufügen:
$roles = App\User::find(1)->roles()->orderBy('name')->get();
Wie zuvor Wie bereits erwähnt, verkettet Eloquent die Namen der beiden relationalen Modelle in alphabetischer Reihenfolge, um den Tabellennamen der relationalen Join-Tabelle zu ermitteln. Natürlich können Sie diese Konvention auch nicht verwenden und einfach den zweiten Parameter an die belongsToMany
-Methode übergeben:
return $this->belongsToMany('App\Role', 'role_user');
Neben der Anpassung des Tabellennamens der Verbindungstabelle können Sie auch zusätzliche Parameter an < übergeben 🎜> Methode zum Definieren des Schlüsselnamens des Felds in der Tabelle. Der dritte Parameter ist der Fremdschlüsselname des Modells, das diese Zuordnung in der Verbindungstabelle definiert, und der vierte Parameter ist der Fremdschlüsselname eines anderen Modells in der Verbindungstabelle: belongsToMany
return $this->belongsToMany('App\Role', 'role_user', 'user_id', 'role_id');Definition Reverse Association Um eine Viele-zu-Viele-Reverse-Assoziation zu definieren, müssen Sie nur die Methode
im Assoziationsmodell aufrufen. Wir definieren die belongsToMany
-Methode im Role
-Modell: users
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Role extends Model{ /** * 拥有此角色的用户。 */ public function users() { return $this->belongsToMany('App\User'); } }Wie Sie sehen können, ist sie genau die gleiche wie die im
-Modell definierte, außer dass das Modell als < eingeführt wird 🎜>. Da wir die Methode AppUser
wiederverwendet haben, gelten hier auch der Tabellenname der benutzerdefinierten Join-Tabelle und der Feldname des Schlüssels in der benutzerdefinierten Join-Tabelle. User
belongsToMany
Holen Sie sich die Zwischentabellenfelder
Wie Sie gerade erfahren haben, benötigen viele-zu-viele-Beziehungen eine Zwischentabelle, um Unterstützung zu bieten. Angenommen, unser User
-Objekt ist mit mehreren Role
-Objekten verknüpft. Nachdem Sie diese zugeordneten Objekte erhalten haben, können Sie das Attribut pivot
des Modells verwenden, um auf die Daten in der Zwischentabelle zuzugreifen:
$user = App\User::find(1); foreach ($user->roles as $role) { echo $role->pivot->created_at; }
Es ist zu beachten, dass jedes Role
Modellobjekt, das wir erhalten, automatisch <🎜 zugewiesen wird > Eigenschaft, die ein Modellobjekt der Zwischentabelle darstellt und wie andere Eloquent-Modelle verwendet werden kann. pivot
-Objekt nur die Primärschlüssel der beiden verwandten Modelle. Wenn Ihre Zwischentabelle weitere zusätzliche Felder enthält, müssen Sie dies bei der Definition der Beziehung explizit angeben: pivot
return $this->belongsToMany('App\Role')->withPivot('column1', 'column2');Wenn Sie möchten, dass die Zwischentabelle die Zeitstempel
und created_at
automatisch verwaltet, fügen Sie beim Definieren der Zuordnung updated_at
hinzu Die Methode lautet: withTimestamps
return $this->belongsToMany('App\Role')->withTimestamps();Benutzerdefinierter
Attributnamepivot
Wie bereits erwähnt, kann über das Attribut auf Attribute aus der Zwischentabelle zugegriffen werden. Es steht Ihnen jedoch frei, den Namen dieser Eigenschaft anzupassen, um ihre Verwendung in Ihrer Anwendung besser widerzuspiegeln. pivot
anstelle von subscription
benennen. Dies kann mithilfe der pivot
-Methode beim Definieren der Beziehung erfolgen: as
return $this->belongsToMany('App\Podcast') ->as('subscription') ->withTimestamps();Nach der Definition können Sie mit einem benutzerdefinierten Namen auf die Zwischentabellendaten zugreifen:
$users = User::with('podcasts')->get(); foreach ($users->flatMap->podcasts as $podcast) { echo $podcast->subscription->created_at; }durch die Zwischentabelle Filterbeziehung Beim Definieren einer Beziehung können Sie auch die Methoden
und wherePivot
zum Filtern verwenden wherePivotIn
Zurückgegebenes Ergebnis: belongsToMany
return $this->belongsToMany('App\Role')->wherePivot('approved', 1); return $this->belongsToMany('App\Role')->wherePivotIn('priority', [1, 2]);
Zwischentabellenmodell definieren
Benutzerdefiniertes Zwischentabellenmodell definieren
Wenn Sie ein benutzerdefiniertes Modell zur Darstellung der Zwischentabelle in der Assoziationsbeziehung definieren möchten, können Sie beim Definieren die Methode using
aufrufen Verein. Benutzerdefinierte 多对多
-Zwischentabellenmodelle müssen von der IlluminateDatabaseEloquentRelationsPivot-Klasse ausgehen, und benutzerdefinierte 多对多(多态)
-Zwischentabellenmodelle müssen die IlluminateDatabaseEloquentRelationsMorphPivot-Klasse erben. Zum Beispiel:
Wenn wir die Zuordnung des Rollenmodells schreiben, verwenden wir das benutzerdefinierte Zwischentabellenmodell UserRole
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Role extends Model{ /** * 拥有此角色的所有用户 */ public function users() { return $this->belongsToMany('App\User')->using('App\UserRole'); } }
Beim Definieren des UserRole
-Modells müssen wir die Klasse Pivot
erweitern :
<?php namespace App; use Illuminate\Database\Eloquent\Relations\Pivot; class UserRole extends Pivot{ // }
Sie können eine Kombination aus using
und withPivot
verwenden, um Spalten aus einer Zwischentabelle abzurufen. Wenn Sie beispielsweise die Spaltennamen an die Methode withPivot
übergeben, können Sie die Spalten UserRole
und created_by
aus der Zwischentabelle updated_by
abrufen.
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Role extends Model{ /** * 拥有此角色的用户。 */ public function users() { return $this->belongsToMany('App\User') ->using('App\UserRole') ->withPivot([ 'created_by', 'updated_by' ]); } }
Benutzerdefiniertes Relay-Modell mit inkrementierender ID
Wenn Sie eine Viele-zu-Viele-Beziehung mit einem benutzerdefinierten Relay-Modell definieren und dieses Das Relay-Modell über eine automatische Inkrementierter Primärschlüssel. Sie sollten sicherstellen, dass die benutzerdefinierte Relay-Modellklasse ein incrementing
-Attribut mit dem Wert true
definiert :
/** * 标识 ID 是否自增。 * * @var bool */ public $incrementing = true;
Remote-Eins-zu-Eins-Beziehung
Remote-Eins-zu-Eins-Zuordnung wird durch eine implementiert Zwischenassoziationsmodell.
Wenn beispielsweise jeder Anbieter einen Benutzer hat und jeder Benutzer mit einem Benutzerverlauf verknüpft ist, kann der Anbieter über den Benutzer auf den Benutzerverlauf zugreifen. Schauen wir uns die Datenbank an, die zum Definieren dieser Beziehungstabelle erforderlich ist:
suppliers id - integer users id - integer supplier_id - integer history id - integer user_id - integer
Obwohl die history
-Tabelle kein supplier_id
enthält, kann die hasOneThrough
-Beziehung Zugriff auf die Benutzerhistorie ermöglichen, um auf das Lieferantenmodell zuzugreifen. Nachdem wir nun die Tabellenstruktur der Beziehung untersucht haben, definieren wir die entsprechende Methode für das Supplier
-Modell:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Supplier extends Model{ /** * 用户的历史记录。 */ public function userHistory() { return $this->hasOneThrough('App\History', 'App\User'); } }
Der erste Parameter, der an die hasOneThrough
-Methode übergeben wird, ist der Name des gewünschten Modells Zugriff und der zweite Der erste Parameter ist der Name des Zwischenmodells.
Bei der Durchführung verwandter Abfragen werden normalerweise die herkömmlichen Fremdschlüsselnamen von Eloquent verwendet. Wenn Sie die zugehörigen Schlüssel anpassen möchten, können Sie dies tun, indem Sie den dritten und vierten Parameter an die Methode hasOneThrough
übergeben. Der dritte Parameter stellt den Fremdschlüsselnamen des Zwischenmodells dar und der vierte Parameter stellt den Fremdschlüssel des dar endgültiger Name. Der fünfte Parameter stellt den lokalen Schlüsselnamen dar, während der sechste Parameter den lokalen Schlüsselnamen des Zwischenmodells darstellt:
class Supplier extends Model{ /** * 用户的历史记录。 */ public function userHistory() { return $this->hasOneThrough( 'App\History', 'App\User', 'supplier_id', // 用户表外键 'user_id', // 历史记录表外键 'id', // 供应商本地键 'id' // 用户本地键 ); } }
Remote-Eins-zu-Viele-Assoziation
Remote-Eins-zu-Viele-Assoziation bietet eine bequeme und kurze Möglichkeit, Assoziationen auf Remote-Ebene über Zwischenassoziationen zu erhalten. Beispielsweise kann ein Country
-Modell über Zwischenmodelle User
mehrere Post
-Modelle erhalten. In diesem Beispiel können Sie ganz einfach alle Blogbeiträge aus einem bestimmten Land sammeln. Werfen wir einen Blick auf die Datentabelle, die zum Definieren dieser Zuordnung erforderlich ist:
countries id - integer name - string users id - integer country_id - integer name - string posts id - integer user_id - integer title - string
Obwohl die Tabelle posts
das Feld country_id
nicht enthält, ermöglicht uns die Zuordnung hasManyThrough
den Zugriff auf eines über $country->posts
Alle Benutzerartikel unter dem Land. Um diese Abfrage abzuschließen, überprüft Eloquent zunächst das Feld users
der Zwischentabelle country_id
und nachdem alle übereinstimmenden Benutzer-IDs gefunden wurden, verwendet Eloquent diese IDs, um die Suche in der Tabelle posts
abzuschließen.
Da wir nun die Datentabellenstruktur kennen, die zum Definieren dieser Zuordnung erforderlich ist, definieren wir sie im Country
Modell:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Country extends Model{ /** * 当前国家所有文章。 */ public function posts() { return $this->hasManyThrough('App\Post', 'App\User'); } }
hasManyThrough
Methodennr. Ein Parameter ist der Name der Modell, auf das wir letztendlich zugreifen möchten, während der zweite Parameter der Name des Zwischenmodells ist.
Bei der Durchführung verwandter Abfragen werden normalerweise die herkömmlichen Fremdschlüsselnamen von Eloquent verwendet. Wenn Sie die zugehörigen Schlüssel anpassen möchten, können Sie dies tun, indem Sie den dritten und vierten Parameter an die Methode hasManyThrough
übergeben. Der dritte Parameter stellt den Fremdschlüsselnamen des Zwischenmodells dar und der vierte Parameter stellt den Fremdschlüssel des dar endgültiger Name. Der fünfte Parameter stellt den lokalen Schlüsselnamen dar, während der sechste Parameter den lokalen Schlüsselnamen des Zwischenmodells darstellt:
class Country extends Model{ public function posts() { return $this->hasManyThrough( 'App\Post', 'App\User', 'country_id', // 用户表外键 'user_id', // 文章表外键 'id', // 国家表本地键 'id' // 用户表本地键 ); } }
Polymorphe Assoziation
Polymorphe Assoziationen ermöglichen die Unterordnung eines Zielmodells mehreren Modellen mit einer einzigen Assoziation.
Eins-zu-eins (polymorph)
Tabellenstruktur
Eine polymorphe Eins-zu-eins-Assoziation ähnelt einer einfachen Eins-zu-eins-Assoziation, das Zielmodell kann jedoch zu mehreren Modellen in einer einzelnen Assoziation gehören. Beispielsweise könnten die Blogs Post
und User
eine Beziehung zum Image
-Modell haben. Die Verwendung einer Eins-zu-Eins-polymorphen Zuordnung ermöglicht die Verwendung einer eindeutigen Liste von Bildern sowohl für Blogbeiträge als auch für Benutzerkonten. Schauen wir uns zunächst die Tabellenstruktur an:
posts id - integer name - string users id - integer name - string images id - integer url - string imageable_id - integer imageable_type - string
Achten Sie besonders auf die Spalten images
und imageable_id
der Tabelle imageable_type
. Die Spalte imageable_id
enthält den ID-Wert des Beitrags oder Benutzers, während die Spalte imageable_type
den Klassennamen des übergeordneten Modells enthält. Eloquent verwendet die Spalte imageable
, um beim Zugriff auf imageable_type
den „Typ“ des übergeordneten Modells zu bestimmen.
Modellstruktur
Als nächstes schauen wir uns die zugehörige Modelldefinition an:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Image extends Model{ /** * 获取拥有此图片的模型。 */ public function imageable() { return $this->morphTo(); } } class Post extends Model{ /** * 获取文章图片。 */ public function image() { return $this->morphOne('App\Image', 'imageable'); } } class User extends Model{ /** * 获取用户图片。 */ public function image() { return $this->morphOne('App\Image', 'imageable'); } }
Abrufen der Zuordnung
Sobald die Tabelle und das Modell definiert sind, kann über das Modell auf diese Zuordnung zugegriffen werden. Um beispielsweise das Artikelbild abzurufen, können Sie das dynamische Attribut image
verwenden:
$post = App\Post::find(1); $image = $post->image;
Sie können das übergeordnete Modell auch aus dem polymorphen Modell abrufen, indem Sie auf den Methodennamen zugreifen, der den Aufruf morphTo
ausführt. In diesem Fall handelt es sich um die Image
-Methode des imageable
-Modells. Wir können also wie eine dynamische Eigenschaft auf diese Methode zugreifen:
$image = App\Image::find(1); $imageable = $image->imageable;
Image
Die imageable
-Zuordnung des Modells gibt entweder eine Post
- oder eine User
-Instanz zurück, je nachdem, um welches Modell es sich bei dem Bildattribut handelt.
Eins-zu-viele (polymorph)
Tabellenstruktur
Eine Eins-zu-Viele-Assoziation ähnelt einer einfachen Eins-zu-Viele-Assoziation, allerdings kann das Zielmodell zu mehreren Modellen in einer einzigen Assoziation gehören. Gehen Sie davon aus, dass Benutzer in der Anwendung gleichzeitig Artikel und Videos „kommentieren“ können. Mithilfe polymorpher Assoziationen können diese Situationen gleichzeitig mit einer einzigen comments
-Tabelle erfüllt werden. Werfen wir zunächst einen Blick auf die Tabellenstruktur, die zum Aufbau dieser Beziehung verwendet wird:
posts id - integer title - string body - text videos id - integer title - string url - string comments id - integer body - text commentable_id - integer commentable_type - string
Modellstruktur
Als nächstes schauen wir uns den Aufbau dieser Beziehung an Modelldefinition der Assoziation:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Comment extends Model{ /** * 获取拥有此评论的模型。 */ public function commentable() { return $this->morphTo(); } } class Post extends Model{ /** * 获取此文章的所有评论。 */ public function comments() { return $this->morphMany('App\Comment', 'commentable'); } } class Video extends Model{ /** * 获取此视频的所有评论。 */ public function comments() { return $this->morphMany('App\Comment', 'commentable'); } }
Zuordnung abrufen
Sobald die Datenbanktabelle und das Modell definiert sind, kann über das Modell auf die Assoziation zugegriffen werden. Sie können beispielsweise mit dem dynamischen Attribut comments
auf alle Kommentare zu einem Artikel zugreifen:
$post = App\Post::find(1);foreach ($post->comments as $comment) { // }
Sie können das Modell, zu dem er gehört, auch aus dem polymorphen Modell abrufen, indem Sie auf den Namen der Methode zugreifen, die das < ausführt 🎜> anrufen. In diesem Fall handelt es sich um die morphTo
-Methode des Comment
-Modells: commentable
$comment = App\Comment::find(1); $commentable = $comment->commentable;
Die Comment
-Zuordnung des Modells gibt entweder eine commentable
- oder eine Post
-Instanz zurück, je nachdem, zu welchem Kommentar sie gehört zum Modellieren. Video
und morphOne
Der Zusammenhang ist etwas komplizierter. Beispielsweise können die Blog-Modelle morphMany
und Post
eine polymorphe Beziehung zum Video
-Modell aufweisen. Die Verwendung einer polymorphen Viele-zu-Viele-Assoziation ermöglicht die gemeinsame Nutzung von Blogbeiträgen und Videos mithilfe eines eindeutigen Tags. Das Folgende ist die Tabellenstruktur einer polymorphen Viele-zu-Viele-Assoziation: Tag
posts id - integer name - string videos id - integer name - string tags id - integer name - string taggables tag_id - integer taggable_id - integer taggable_type - stringModellstrukturAls nächstes definieren Sie die Assoziation für das Modell. Sowohl das
- als auch das Post
-Modell verfügen über Video
-Methoden, die die morphToMany
-Methode der Eloquent-Basisklasse aufrufen: tags
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Post extends Model{ /** * 获取文章的所有标签。 */ public function tags() { return $this->morphToMany('App\Tag', 'taggable'); } }
Definieren Sie die umgekehrte Assoziationsbeziehung
Als nächstes müssen Sie eine Methode für jedes Assoziationsmodell im Tag
-Modell definieren. In diesem Beispiel definieren wir die posts
-Methode und die videos
-Methode:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Tag extends Model{ /** * 获取被打上此标签的所有文章。 */ public function posts() { return $this->morphedByMany('App\Post', 'taggable'); } /** * 获取被打上此标签的所有视频。 */ public function videos() { return $this->morphedByMany('App\Video', 'taggable'); } }
Erhalten Sie die Zuordnung
Sobald die Datenbanktabelle und das Modell definiert sind, Greifen Sie über das Modell auf die Zuordnung zu. Sie können beispielsweise das dynamische Attribut tags
verwenden, um auf alle Tags des Artikels zuzugreifen:
$post = App\Post::find(1);foreach ($post->tags as $tag) { // }
Sie können auch auf den Methodennamen zugreifen, der den Methodenaufruf morphedByMany
ausführt, um das Modell abzurufen, zu dem es gehört das polymorphe Modell. In diesem Beispiel handelt es sich um die Methode Tag
oder posts
des Modells videos
. Auf diese Methoden kann wie auf dynamische Eigenschaften zugegriffen werden:
$tag = App\Tag::find(1);foreach ($tag->videos as $video) { // }
Benutzerdefinierter polymorpher Typ
Standardmäßig Laravel Store zugeordnetes Modell Typen unter Verwendung vollständig qualifizierter Klassennamen. Da im obigen Eins-zu-viele-Beispiel Comment
entweder zu einem Post
oder einem Video
gehören kann, lautet der Standardwert für commentable_type
jeweils AppPost
bzw. AppVideo
. Möglicherweise möchten Sie jedoch die Datenbank von der internen Struktur Ihrer Anwendung entkoppeln. In diesem Fall können Sie eine „Morph Map“ definieren, um Eloquent anzuweisen, einen benutzerdefinierten Namen anstelle des entsprechenden Klassennamens zu verwenden:
use Illuminate\Database\Eloquent\Relations\Relation; Relation::morphMap([ 'posts' => 'App\Post', 'videos' => 'App\Video', ]);
kann in der AppServiceProvider
-Funktion von boot
oder in der Funktion „Erstellen“ registriert werden ein separater Dienstleister. morphMap
-Modell eines Blogsystems hat viele zugehörige User
-Modelle: Post
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model{ /** * 获取该用户的所有文章。 */ public function posts() { return $this->hasMany('App\Post'); } }Sie können die
-Zuordnungen abfragen und ihnen zusätzliche Einschränkungen hinzufügen: posts
$user = App\User::find(1); $user->posts()->where('active', 1)->get();Sie können jeden Abfrage-Builder für die Zuordnung verwenden Methoden finden Sie in der Dokumentation zum Abfrage-Generator, um zu erfahren, welche Methoden für Sie nützlich sein könnten.
Relationsmethoden vs. dynamische Eigenschaften
Wenn Sie Ihrer Eloquent-Relationsabfrage keine zusätzlichen Einschränkungen hinzufügen müssen, können Sie auf die Relation wie auf eine Eigenschaft zugreifen. Wenn Sie beispielsweise weiterhin die Beispielmodelle User
und Post
verwenden, können Sie auf alle Artikel des Benutzers wie folgt zugreifen:
$user = App\User::find(1); foreach ($user->posts as $post) { // }
Dynamische Eigenschaften werden „verzögert geladen“, was bedeutet, dass sie nur geladen werden, wenn Sie greifen tatsächlich auf die zugehörigen Daten zu. Daher verwenden Entwickler häufig Vorladen, um Beziehungen vorab zu laden, von denen sie wissen, dass sie nach dem Laden des Modells darauf zugreifen werden. Bei SQL-Abfragen, die beim Laden von Modellzuordnungen ausgeführt werden müssen, reduziert Eager Loading die Anzahl der Abfrageausführungen erheblich.
Bestehende Beziehungen abfragen
Beim Zugriff auf Modelldatensätze möchten Sie möglicherweise die Abfrageergebnisse basierend auf der Existenz von einschränken die Beziehung. Wenn Sie beispielsweise alle Artikel mit mindestens einem Kommentar erhalten möchten, können Sie den Assoziationsnamen an die Methoden has
und orHas
übergeben:
// 获取至少存在一条评论的所有文章... $posts = App\Post::has('comments')->get();
Außerdem können Sie den Operator und die Menge weiter angeben Passen Sie die Abfrage an:
// 获取评论超过三条的文章... $posts = App\Post::has('comments', '>=', 3)->get();
kann auch die „Punkt“-Syntax verwenden, um verschachtelte has
-Anweisungen zu erstellen. Sie können beispielsweise Artikel mit mindestens einem Kommentar erhalten und abstimmen:
// 获取拥有至少一条带有投票评论的文章... $posts = App\Post::has('comments.votes')->get();
Wenn Sie mehr Funktionalität benötigen, können Sie die Methoden whereHas
und orWhereHas
verwenden, um die „Where“-Bedingung auf das < zu setzen 🎜> Abfrage. Mit diesen Methoden können Sie benutzerdefinierte Einschränkungen zur Zuordnung hinzufügen, z. B. die Überprüfung des Kommentarinhalts: has
use Illuminate\Database\Eloquent\Builder; // 获取至少带有一条评论内容包含 foo% 关键词的文章... $posts = App\Post::whereHas('comments', function ($query) { $query->where('content', 'like', 'foo%');})->get(); // 获取至少带有十条评论内容包含 foo% 关键词的文章... $posts = App\Post::whereHas('comments', function ($query) { $query->where('content', 'like', 'foo%'); }, '>=', 10)->get();Abfrage nach nicht vorhandenen Zuordnungen Beim Zugriff auf Modelldatensätze möchten Sie möglicherweise die Abfrageergebnisse basierend auf dem Nichtvorhandensein der Zuordnung einschränken. Angenommen, Sie möchten
Artikel erhalten, die keine Kommentare haben. Sie können dies tun, indem Sie den Assoziationsnamen an die Methoden und doesntHave
übergeben: orDoesntHave
$posts = App\Post::doesntHave('comments')->get();Wenn Sie mehr benötigen Funktionalität können Sie < verwenden. Die Methoden 🎜> und
fügen der whereDoesntHave
-Abfrage „Where“-Bedingungen hinzu. Mit diesen Methoden können Sie der Zuordnung benutzerdefinierte Einschränkungen hinzufügen, z. B. das Erkennen von Kommentarinhalten: orWhereDoesntHave
use Illuminate\Database\Eloquent\Builder; $posts = App\Post::whereDoesntHave('comments', function (Builder $query) { $query->where('content', 'like', 'foo%'); })->get();
doesntHave
Sie können auch die „Punkt“-Syntax verwenden, um verschachtelte Zuordnungsabfragen durchzuführen. Die folgende Abfrage ruft beispielsweise Artikel mit Kommentaren von Autoren ab, die nicht gesperrt wurden: use Illuminate\Database\Eloquent\Builder; $posts = App\Post::whereDoesntHave('comments.author', function (Builder $query) { $query->where('banned', 1); })->get();
Zugehörige Modellanzahl
Wenn Sie nur die statistische Anzahl der zugehörigen Ergebnisse zählen möchten, ohne sie tatsächlich zu laden, können Sie die Methode withCount
verwenden, die in der Spalte {relation}_count
des platziert wird Ergebnismodell. Ein Beispiel lautet wie folgt:
$posts = App\Post::withCount('comments')->get(); foreach ($posts as $post) { echo $post->comments_count; }
Sie können „Zählungen“ zu mehreren Beziehungen hinzufügen, genau wie das Hinzufügen von Einschränkungen zu Abfragen:
$posts = App\Post::withCount(['votes', 'comments' => function ($query) { $query->where('content', 'like', 'foo%'); }])->get(); echo $posts[0]->votes_count;echo $posts[0]->comments_count;
Sie können die Ergebnisse der Beziehungsanzahl auch mit einem Alias versehen, was Ihnen das Hinzufügen ermöglicht „zählt“ auf derselben Beziehung. Mehrere Zählungen:
$posts = App\Post::withCount([ 'comments', 'comments as pending_comments_count' => function ($query) { $query->where('approved', false); }])->get(); echo $posts[0]->comments_count; echo $posts[0]->pending_comments_count;
Wenn Sie withCount
- und select
-Abfragen zusammenfügen, achten Sie darauf, sie zu addieren select
wird nach der Methode aufgerufen: withCount
$query = App\Post::select(['title', 'body'])->withCount('comments'); echo $posts[0]->title; echo $posts[0]->body; echo $posts[0]->comments_count;PreloadingBeim Zugriff auf eine Eloquent-Assoziation als Eigenschaft, Die Assoziationsdaten werden „verzögert geladen“. Auf diese Weise werden die zugehörigen Daten erst beim ersten Zugriff auf die Eigenschaft tatsächlich geladen. Allerdings kann Eloquent beim Abfragen des übergeordneten Modells untergeordnete Beziehungen „vorab laden“. Durch eifriges Laden kann das N 1-Abfrageproblem gemildert werden. Um das N 1-Abfrageproblem zu veranschaulichen, betrachten Sie den Fall, in dem das
-Modell mit Book
verknüpft ist: Author
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Book extends Model{ /** * 获取书籍作者。 */ public function author() { return $this->belongsTo('App\Author'); } }Nun holen wir uns alle Bücher und ihre Autoren:
$books = App\Book::all(); foreach ($books as $book) { echo $book->author->name; }Diese Schleife führt eine Abfrage aus, um alle Bücher abzurufen, und führt dann für jedes Buch eine Abfrage aus, um den Autor abzurufen. Wenn wir 25 Bücher haben, führt diese Schleife 26 Abfragen aus: 1 zur Abfrage des Buchs und 25 zusätzliche Abfragen zur Abfrage des Autors jedes Buchs. Glücklicherweise konnten wir Eager Loading verwenden, um den Vorgang auf nur zwei Abfragen zu reduzieren. Zum Zeitpunkt der Abfrage können Sie die Methode
verwenden, um die Zuordnungen anzugeben, die Sie vorab laden möchten: with
$books = App\Book::with('author')->get(); foreach ($books as $book) { echo $book->author->name; }In diesem Beispiel wurden nur zwei Abfragen ausgeführt:
select * from books select * from authors where id in (1, 2, 3, 4, 5, ...)Mehrere Zuordnungen vorab laden Manchmal müssen Sie möglicherweise mehrere verschiedene Zuordnungen in einem einzigen Vorgang vorab laden. Um dies zu erreichen, übergeben Sie einfach einen Array-Parameter, der aus mehreren zugehörigen Namen besteht, an die Methode
: with
$books = App\Book::with(['author', 'publisher'])->get();Geschachteltes Vorladen kann die „Punkt“-Syntax verwenden. Vorladen verschachtelt Verbände. Zum Beispiel das Vorabladen aller Buchautoren und ihrer Kontaktinformationen in einer eloquenten Aussage:
$books = App\Book::with('author.contacts')->get();Vorabladen bestimmter Spalten Es ist nicht immer notwendig, jede Spalte der Beziehung abzurufen . In diesem Fall können Sie mit Eloquent die Spalten angeben, die Sie für die Zuordnung erhalten möchten:
$users = App\Book::with('author:id,name')->get();
{note} Wenn Sie diese Funktion verwenden, achten Sie darauf, <🎜 in die Liste der abzurufenden Spalten aufzunehmen > Spalte.
id
Einschränkungen für das Vorladen hinzufügen
Manchmal möchten Sie möglicherweise eine Beziehung vorab laden und der Vorladeabfrage zusätzliche Abfragebedingungen hinzufügen, wie im folgenden Beispiel:
$users = App\User::with(['posts' => function ($query) { $query->where('title', 'like', '%first%'); }])->get();
In diesem Beispiel wird Eloquent dies tun Laden Sie nur die Artikel vor, deren Spalte title
das Schlüsselwort first
enthält. Sie können auch andere Abfrage-Builder-Methoden aufrufen, um den Vorladevorgang weiter anzupassen:
$users = App\User::with(['posts' => function ($query) { $query->orderBy('created_at', 'desc'); }])->get();
{note} Beim Einschränken des Vorladens können die Abfrage-Builder-Methoden
limit
undtake
nicht verwendet werden.
Vorladen
Vielleicht möchten Sie auch Eager Loading durchführen, nachdem das Modell geladen wurde. Wenn Sie beispielsweise verwandte Daten dynamisch laden möchten, ist die Methode load
für Sie sehr nützlich:
$books = App\Book::all(); if ($someCondition) { $books->load('author', 'publisher'); }
Wenn Sie die Abfrage beim Eager Loading bedingt einschränken möchten, können Sie sie in laden Form eines Arrays, der Schlüssel ist die entsprechende Assoziation, der Wert ist eine Closure
-Abschlussfunktion, der Parameter des Abschlusses ist ein query
Beispiel:
$books->load(['author' => function ($query) { $query->orderBy('published_date', 'asc'); }]);
Wenn die Beziehung nicht geladen ist, können Sie die loadMissing
-Methode verwenden:
public function format(Book $book){ $book->loadMissing('author'); return [ 'name' => $book->name, 'author' => $book->author->name ]; }
Nested Lazy Loading & morphTo
Wenn Sie die morphTo
-Beziehung sowie die verschachtelten Beziehungen zu den verschiedenen Entitäten, die die Beziehung möglicherweise zurückgibt, schnell laden möchten, können Sie diese verwenden loadMorph
Methode.
Diese Methode akzeptiert den Namen der morphTo
-Beziehung als ersten Parameter und der zweite Parameter empfängt ein Modellarray und ein Beziehungsarray. Schauen Sie sich zur Veranschaulichung dieses Ansatzes das folgende Modellbeispiel an:
<?php use Illuminate\Database\Eloquent\Model; class ActivityFeed extends Model{ /** * Get the parent of the activity feed record. */ public function parentable() { return $this->morphTo(); } }
Nehmen wir in diesem Beispiel an, dass die Modelle Event
, Photo
und Post
das Modell ActivityFeed
erstellen können. Nehmen wir außerdem an, dass das Modell Event
zum Modell Calendar
gehört, das Modell Photo
dem Modell Tag
zugeordnet ist und das Modell Post
zum Modell Author
gehört.
Mithilfe dieser Modelldefinitionen und Beziehungen können wir die ActivityFeed
Modellinstanz abrufen und alle parentable
Modelle und ihre jeweiligen verschachtelten Beziehungen auf einmal laden:
$activities = ActivityFeed::with('parentable') ->get() ->loadMorph('parentable', [ Event::class => ['calendar'], Photo::class => ['tags'], Post::class => ['author'], ]);
Einfügen & Zugehöriges Modell aktualisieren
Speichermethode
Eloquent bietet eine praktische Möglichkeit, Assoziationen zu neuen Modellen hinzuzufügen. Beispielsweise müssen Sie möglicherweise ein neues Comment
zu einem Post
-Modell hinzufügen. Sie müssen das Comment
-Attribut in post_id
nicht manuell festlegen, sondern können direkt die save
-Methode des zugehörigen Modells verwenden, um Comment
direkt einzufügen:
$comment = new App\Comment(['message' => 'A new comment.']); $post = App\Post::find(1); $post->comments()->save($comment);
Es sollte beachtet werden Wir verwenden keine dynamischen Attribute, um auf die comments
-Zuordnung zuzugreifen. Stattdessen rufen wir die Methode comments
auf, um die zugehörige Instanz abzurufen. Die save
-Methode fügt dem post_id
-Modell automatisch die entsprechenden Comment
-Werte hinzu.
Wenn Sie mehrere verknüpfte Modelle speichern müssen, können Sie die Methode saveMany
verwenden:
$post = App\Post::find(1); $post->comments()->saveMany([ new App\Comment(['message' => 'A new comment.']), new App\Comment(['message' => 'Another comment.']), ]);
Speichern rekursive Modelle und verknüpfte Daten
Wenn Sie möchtensave
Für Ihr Modell und alle zugehörigen Daten können Sie die Methode push
verwenden:
$post = App\Post::find(1); $post->comments[0]->message = 'Message'; $post->comments[0]->author->name = 'Author Name';$post->push();
Neue Methode
Zusätzlich zu den Methoden save
und saveMany
können Sie auch die Methode create
verwenden. Es akzeptiert eine Reihe von Eigenschaften, erstellt ein Modell und fügt es in die Datenbank ein. Der Unterschied zwischen der save
-Methode und der create
-Methode besteht außerdem darin, dass die save
-Methode eine vollständige Eloquent-Modellinstanz akzeptiert, während create
ein normales PHP-Array akzeptiert:
$post = App\Post::find(1); $comment = $post->comments()->create([ 'message' => 'A new comment.', ]);
{Tipp} Bevor Sie die
create
-Methode verwenden, lesen Sie bitte unbedingt das Kapitel zur Stapelzuweisung in diesem Dokument.
Sie können auch die createMany
-Methode verwenden, um mehrere verwandte Modelle zu erstellen:
$post = App\Post::find(1);$post->comments()->createMany([ [ 'message' => 'A new comment.', ], [ 'message' => 'Another new comment.', ], ]);
Sie können auch findOrNew
, firstOrNew
, firstOrCreate
und updateOrCreate
verwenden Verfahren Erstellen und aktualisieren Sie Beziehungsmodelle.
belongsTo
Assoziation aktualisieren
Beim Aktualisieren einer belongsTo
Assoziation müssen Sie Sie können die Methode associate
verwenden. Diese Methode legt den Fremdschlüssel im untergeordneten Modell fest:
$account = App\Account::find(10); $user->account()->associate($account);$user->save();
Die belongsTo
-Methode kann beim Entfernen der dissociate
-Zuordnung verwendet werden. Diese Methode setzt den zugehörigen Fremdschlüssel auf null
:
$user->account()->dissociate();$user->save();Mit der Beziehung
Standardmodell
belongsTo
können Sie ein Standardmodell angeben. Wenn die angegebene Beziehung null
ist, wird das Standardmodell zurückgegeben. Dieses Muster wird als Nullobjektmuster bezeichnet und kann unnötige Überprüfungen in Ihrem Code reduzieren. Wenn im folgenden Beispiel kein Autor für den veröffentlichten Beitrag gefunden wird, gibt die user
-Beziehung ein leeres AppUser
-Modell zurück:
/** * 获取帖子的作者。 */ public function user(){ return $this->belongsTo('App\User')->withDefault(); }
Wenn Sie dem Standardmodell Attribute hinzufügen müssen, können Sie übergeben ein Array oder eine Rückrufmethode für withDefault
Medium:
/** * 获取帖子的作者。 */ public function user(){ return $this->belongsTo('App\User')->withDefault([ 'name' => 'Guest Author', ]); } /** * 获取帖子的作者。 */ public function user(){ return $this->belongsTo('App\User')->withDefault(function ($user) { $user->name = 'Guest Author'; }); }
Many-to-Many-Assoziation
Anhängen/Abtrennen
Eloquent Darüber hinaus werden einige zusätzliche Hilfsmethoden bereitgestellt, um die Verwendung verwandter Modelle komfortabler zu gestalten. Nehmen wir beispielsweise an, dass ein Benutzer mehrere Rollen haben kann und jede Rolle von mehreren Benutzern gemeinsam genutzt werden kann. Das Anhängen einer Rolle an einen Benutzer erfolgt durch Einfügen eines Datensatzes in die Zwischentabelle. Dieser Vorgang kann mit der attach
-Methode durchgeführt werden:
$user = App\User::find(1); $user->roles()->attach($roleId);
Beim Anhängen einer Beziehung an ein Modell können Sie auch einen Satz übergeben der einzufügenden Werte:
$user->roles()->attach($roleId, ['expires' => $expires]);
Natürlich ist es manchmal auch notwendig, die Rolle des Benutzers zu entfernen. Viele-zu-viele-bezogene Datensätze können mit detach
entfernt werden. Die Methode detach
entfernt die entsprechenden Datensätze aus der Zwischentabelle; beide Modelle bleiben jedoch in der Datenbank:
// 移除用户的一个角色... $user->roles()->detach($roleId); // 移除用户的所有角色... $user->roles()->detach();
Der Einfachheit halber erlauben attach
und detach
auch die Übergabe eines ID-Arrays :
$user = App\User::find(1); $user->roles()->detach([1, 2, 3]); $user->roles()->attach([ 1 => ['expires' => $expires], 2 => ['expires' => $expires] ]);
Synchronisierungszuordnung
Sie können auch verwenden sync
Methode zum Aufbau einer Viele-zu-Viele-Assoziation. Die Methode sync
empfängt ein Array von IDs, um die Datensätze der Zwischentabelle zu ersetzen. Unter den Zwischentabellendatensätzen werden alle Datensätze entfernt, die nicht im ID-Array enthalten sind. Nach Abschluss des Vorgangs bleibt also nur die ID des angegebenen Arrays in der Zwischentabelle erhalten:
$user->roles()->sync([1, 2, 3]);
Sie können der Zwischentabelle auch zusätzliche Daten über die ID übergeben:
$user->roles()->sync([1 => ['expires' => true], 2, 3]);
Wenn Sie die vorhandene ID nicht entfernen möchten, können Sie syncWithoutDetaching
verwenden Methoden:
$user->roles()->syncWithoutDetaching([1, 2, 3]);
Zuordnung wechseln
Many-to-many-Zuordnung bietet auch die toggle
-Methode zum „Umschalten“ des zusätzlichen Status eines bestimmten ID-Arrays. Wenn die angegebene ID in der Zwischentabelle angehängt wurde, wird sie entfernt. Wenn die angegebene ID entfernt wurde, wird sie ebenfalls angehängt:
$user->roles()->toggle([1, 2, 3]);
Zusätzliche Daten speichern unter Zwischentabellen
Speichern Sie beim Umgang mit Viele-zu-Viele-Beziehungen Als zweiten Parameter erhält die Methode ein zusätzliches Datenarray:
App\User::find(1)->roles()->save($role, ['expires' => $expires]);
Zwischentabellendatensatz aktualisieren
Wenn Sie einen vorhandenen Datensatz in der Zwischentabelle aktualisieren müssen, können Sie updateExistingPivot
verwenden. Diese Methode empfängt den Fremdschlüssel der Zwischentabelle und das zu aktualisierende Datenarray für die Aktualisierung:
$user = App\User::find(1); $user->roles()->updateExistingPivot($roleId, $attributes);
Update parent timestamp
Wenn ein Modell zu belongsTo
oder belongsToMany
zu einem anderen Modell gehört, gehört beispielsweise Comment
zu Post
Manchmal ist es nützlich, ein untergeordnetes Modell zu aktualisieren, was zu einem aktualisierten Zeitstempel des übergeordneten Modells führt. Wenn beispielsweise das Comment
-Modell aktualisiert wird, möchten Sie automatisch eine Aktualisierung des Post
-Zeitstempels des übergeordneten updated_at
-Modells „auslösen“. Eloquent macht es einfach. Fügen Sie einfach ein touches
-Attribut hinzu, das den zugehörigen Namen zum untergeordneten Modell enthält:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Comment extends Model{ /** * 要触发的所有关联关系 * * @var array */ protected $touches = ['post']; /** * 评论所属的文章 */ public function post() { return $this->belongsTo('App\Post'); } }
Wenn Sie nun ein Comment
aktualisieren, wird auch das Post
-Feld, das dem übergeordneten updated_at
-Modell entspricht, auf aktualisiert Machen Sie es einfacher zu wissen, wann der Cache eines Post
Modells ungültig gemacht werden muss:
$comment = App\Comment::find(1); $comment->text = 'Edit to this comment!'; $comment->save();