Znalazłem pojęcie i znaczenie za tych metod, aby być trochę mylące, to jest możliwe, aby ktoś mi wyjaśnić, jaka jest różnica między has
i with
jest w tym kontekście przykład (jeśli to możliwe)?
Znalazłem pojęcie i znaczenie za tych metod, aby być trochę mylące, to jest możliwe, aby ktoś mi wyjaśnić, jaka jest różnica między has
i with
jest w tym kontekście przykład (jeśli to możliwe)?
Odpowiedzi:
with()
jest do chętnego ładowania . Zasadniczo oznacza to, że zgodnie z głównym modelem Laravel wstępnie załaduje określone relacje. Jest to szczególnie przydatne, jeśli masz kolekcję modeli i chcesz załadować relację dla wszystkich z nich. Ponieważ przy chętnym ładowaniu uruchamiasz tylko jedno dodatkowe zapytanie DB zamiast jednego dla każdego modelu w kolekcji.
Przykład:
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()
jest filtrowanie wybranego modelu na podstawie relacji. Więc działa bardzo podobnie do normalnego GDZIE. Jeśli po prostu użyjesz has('relation')
, oznacza to, że chcesz tylko uzyskać modele, które mają co najmniej jeden powiązany model w tej relacji.
Przykład:
User > hasMany > Post
$users = User::has('posts')->get();
// only users that have at least one post are contained in the collection
whereHas()
działa w zasadzie tak samo, has()
ale pozwala określić dodatkowe filtry dla powiązanego modelu do sprawdzenia.
Przykład:
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
relacji z użytkownikami podczas wysyłania zapytań.
whereHas
tego, use Illuminate\Database\Eloquent\Builder;
co wtedy jest function(Builder $query)
. Większość przykładów, które widziałem, używa kropki Builder
, wystarczy podać zapytanie $, która jest właściwa metoda?
Dokument wyjaśnił już użycie. Więc używam SQL do wyjaśnienia tych metod
Zakładając, że jest Order (orders)
wiele OrderItem (order_items)
.
I już zbudowałeś relacje między nimi.
// App\Models\Order:
public function orderItems() {
return $this->hasMany('App\Models\OrderItem', 'order_id', 'id');
}
Te trzy metody opierają się na relacji .
Wynik: with()
zwróć obiekt modelu i powiązane wyniki.
Zaleta: jest chętna do ładowania, która może zapobiec problemowi N + 1 .
Gdy używasz następującego Eloquent Buildera:
Order::with('orderItems')->get();
Laravel zmienia ten kod na tylko dwa 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...);
Następnie laravel scala wyniki drugiego SQL jako różne od wyników pierwszego SQL według klucza obcego . W końcu zwróć wyniki kolekcji.
Więc jeśli wybierzesz kolumny bez klucza obcego w zamknięciu, wynik relacji będzie pusty:
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
zwróci obiekt modelu, że jego związek nie jest pusty .
Order::has('orderItems')->get();
Laravel zmień ten kod na jeden SQL :
select * from `orders` where exists (
select * from `order_items` where `order`.`id` = `order_item`.`order_id`
)
whereHas
i orWhereHas
metody ustalania where
warunków dla twoich has
zapytań. Te metody pozwalają dodawać niestandardowe wiązania do ograniczenia relacji .
Order::whereHas('orderItems', function($query) {
$query->where('status', 1);
})->get();
Laravel zmień ten kod na jeden SQL :
select * from `orders` where exists (
select *
from `order_items`
where `orders`.`id` = `order_items`.`order_id` and `status` = 1
)
with('relation')
będzie zawierać dane tabeli pokrewnej w zwróconej kolekcjihas('relation')
i niewhereHas('relation')
będzie zawierał danych tabeli pokrewnej. Więc może trzeba zadzwonić zarówno jak i .with('relation')
has()
whereHas()