Ho trovato il concetto e il significato dietro questi metodi per essere un po 'confuso, è possibile per qualcuno spiegarmi qual è la differenza tra hased 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 hased 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
whereHasla relazione utente durante la query di posta.
whereHaslo 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
}...
}]
Hasrestituirà 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`
)
whereHase orWhereHasmetodi per porre wherecondizioni alle tue hasdomande. 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().