Ich habe das Konzept und die Bedeutung dieser Methoden als etwas verwirrend empfunden. Kann mir jemand erklären, was der Unterschied zwischen has
und with
im Kontext eines Beispiels ist (wenn möglich)?
Ich habe das Konzept und die Bedeutung dieser Methoden als etwas verwirrend empfunden. Kann mir jemand erklären, was der Unterschied zwischen has
und with
im Kontext eines Beispiels ist (wenn möglich)?
Antworten:
with()
ist zum eifrigen Laden . Das bedeutet im Grunde, dass Laravel entlang des Hauptmodells die von Ihnen angegebenen Beziehungen vorlädt. Dies ist besonders hilfreich, wenn Sie über eine Sammlung von Modellen verfügen und für alle eine Beziehung laden möchten. Denn beim eifrigen Laden führen Sie nur eine zusätzliche DB-Abfrage anstelle einer für jedes Modell in der Sammlung aus.
Beispiel:
User > hasMany > Post
$users = User::with('posts')->get();
foreach($users as $user){
$users->posts; // posts is already loaded and no additional DB query is run
}
has()
besteht darin, das Auswahlmodell basierend auf einer Beziehung zu filtern. Es verhält sich also sehr ähnlich zu einem normalen WHERE-Zustand. Wenn Sie nur verwenden has('relation')
, bedeutet dies, dass Sie nur die Modelle erhalten möchten, die mindestens ein verwandtes Modell in dieser Beziehung haben.
Beispiel:
User > hasMany > Post
$users = User::has('posts')->get();
// only users that have at least one post are contained in the collection
whereHas()
funktioniert im Grunde genauso wie has()
, ermöglicht es Ihnen jedoch, zusätzliche Filter für das zu überprüfende zugehörige Modell anzugeben.
Beispiel:
User > hasMany > Post
$users = User::whereHas('posts', function($q){
$q->where('created_at', '>=', '2015-01-01 00:00:00');
})->get();
// only users that have posts from 2015 on forward are returned
whereHas
auf Benutzerbeziehung, wenn Sie Beitrag abfragen.
whereHas
es verwendet wird, use Illuminate\Database\Eloquent\Builder;
was dann mit ist function(Builder $query)
. Die meisten Beispiele, die ich gesehen habe, Punkt verwenden die Builder
, übergeben Sie einfach die $ Abfrage, was ist der richtige Weg?
Dokument hat die Verwendung bereits erklärt. Ich benutze SQL, um diese Methoden zu erklären
Vorausgesetzt, es gibt Order (orders)
viele OrderItem (order_items)
.
Und Sie haben bereits die Beziehung zwischen ihnen aufgebaut.
// App\Models\Order:
public function orderItems() {
return $this->hasMany('App\Models\OrderItem', 'order_id', 'id');
}
Diese drei Methoden basieren alle auf einer Beziehung .
Ergebnis: with()
Gibt das Modellobjekt und die zugehörigen Ergebnisse zurück.
Vorteil: Es ist ein eifriges Laden, das das N + 1-Problem verhindern kann .
Wenn Sie den folgenden Eloquent Builder verwenden:
Order::with('orderItems')->get();
Laravel ändert diesen Code in nur zwei SQL :
// get all orders:
SELECT * FROM orders;
// get the order_items based on the orders' id above
SELECT * FROM order_items WHERE order_items.order_id IN (1,2,3,4...);
Und dann führt Laravel die Ergebnisse des zweiten SQL anders als die Ergebnisse des ersten SQL nach Fremdschlüssel zusammen . Geben Sie endlich die Sammlungsergebnisse zurück.
Wenn Sie also Spalten ohne den Fremdschlüssel im Abschluss ausgewählt haben, ist das Beziehungsergebnis leer:
Order::with(['orderItems' => function($query) {
// $query->sum('quantity');
$query->select('quantity'); // without `order_id`
}
])->get();
#=> result:
[{ id: 1,
code: '00001',
orderItems: [], // <== is empty
},{
id: 2,
code: '00002',
orderItems: [], // <== is empty
}...
}]
Has
gibt das Objekt des Modells zurück, dessen Beziehung nicht leer ist .
Order::has('orderItems')->get();
Laravel ändert diesen Code in ein SQL :
select * from `orders` where exists (
select * from `order_items` where `order`.`id` = `order_item`.`order_id`
)
whereHas
und orWhereHas
Methoden, um where
Bedingungen für Ihre has
Abfragen festzulegen. Mit diesen Methoden können Sie einer Beziehungsbeschränkung benutzerdefinierte Einschränkungen hinzufügen .
Order::whereHas('orderItems', function($query) {
$query->where('status', 1);
})->get();
Laravel ändert diesen Code in ein SQL :
select * from `orders` where exists (
select *
from `order_items`
where `orders`.`id` = `order_items`.`order_id` and `status` = 1
)
with('relation')
die Maßgebliche Tabelle der Daten in der zurückgegebenen Sammlung gehört,has('relation')
undwhereHas('relation')
wird nicht die Daten der verknüpften Tabelle. Möglicherweise müssen Sie sowohlwith('relation')
als auchhas()
oder anrufenwhereHas()
.