Ho trovato il concetto e il significato dietro questi metodi per essere un po 'confuso, è possibile per qualcuno spiegarmi qual è la differenza tra has
ed with
è, nel contesto di un esempio (se possibile)?
Ho trovato il concetto e il significato dietro questi metodi per essere un po 'confuso, è possibile per qualcuno spiegarmi qual è la differenza tra has
ed with
è, nel contesto di un esempio (se possibile)?
Risposte:
with()
è per il caricamento desideroso . Ciò significa sostanzialmente che, lungo il modello principale, Laravel precaricherà le relazioni specificate. Ciò è particolarmente utile se si dispone di una raccolta di modelli e si desidera caricare una relazione per tutti loro. Perché con il caricamento desideroso si esegue solo una query DB aggiuntiva anziché una per ogni modello nella raccolta.
Esempio:
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()
è filtrare il modello selezionato in base a una relazione. Quindi agisce in modo molto simile a una normale condizione WHERE. Se lo usi, has('relation')
significa che vuoi solo ottenere i modelli che hanno almeno un modello correlato in questa relazione.
Esempio:
User > hasMany > Post
$users = User::has('posts')->get();
// only users that have at least one post are contained in the collection
whereHas()
funziona sostanzialmente come, has()
ma consente di specificare filtri aggiuntivi per il controllo del modello correlato.
Esempio:
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
la relazione utente durante la query di posta.
whereHas
lo si utilizza utilizza use Illuminate\Database\Eloquent\Builder;
quindi function(Builder $query)
. La maggior parte degli esempi che ho visto, dot usa il Builder
, basta passare nella $ query, qual è la strada giusta?
Il documento ha già spiegato l'utilizzo. Quindi sto usando SQL per spiegare questi metodi
Supponendo che ce ne siano Order (orders)
molti OrderItem (order_items)
.
E hai già costruito il rapporto tra loro.
// App\Models\Order:
public function orderItems() {
return $this->hasMany('App\Models\OrderItem', 'order_id', 'id');
}
Questi tre metodi sono tutti basati su una relazione .
Risultato: with()
restituisce l'oggetto modello e i relativi risultati.
Vantaggio: è il caricamento impaziente che può prevenire il problema N + 1 .
Quando si utilizza il seguente generatore di eloquenti:
Order::with('orderItems')->get();
Laravel cambia questo codice in solo due 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...);
E poi laravel unisce i risultati del secondo SQL in modo diverso dai risultati del primo SQL con chiave esterna . Alla fine restituisci i risultati della raccolta.
Quindi se hai selezionato le colonne senza la chiave_estra in chiusura, il risultato della relazione sarà vuoto:
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
restituirà l'oggetto del modello che la sua relazione non è vuota .
Order::has('orderItems')->get();
Laravel cambia questo codice in un SQL :
select * from `orders` where exists (
select * from `order_items` where `order`.`id` = `order_item`.`order_id`
)
whereHas
e orWhereHas
metodi per porre where
condizioni alle tue has
domande. Questi metodi consentono di aggiungere vincoli personalizzati a un vincolo di relazione .
Order::whereHas('orderItems', function($query) {
$query->where('status', 1);
})->get();
Laravel cambia questo codice in un SQL :
select * from `orders` where exists (
select *
from `order_items`
where `orders`.`id` = `order_items`.`order_id` and `status` = 1
)
with('relation')
includerà i dati del relativo della tabella nella collezione restituita,has('relation')
ewhereHas('relation')
sarà non includono i dati della relativa tabella. Quindi potrebbe essere necessario chiamare siawith('relation')
così comehas()
owhereHas()
.