답변:
with()
위한 열망로드 . 기본적으로 라 라벨은 사용자가 지정한 관계를 미리로드한다는 의미입니다. 모델 모음이 있고 모든 모델에 대한 관계를로드하려는 경우 특히 유용합니다. 로딩이 열리기 때문에 컬렉션의 모든 모델에 대해 하나가 아닌 하나의 추가 DB 쿼리 만 실행하기 때문입니다.
예:
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()
관계에 따라 선택 모델을 필터링하는 것입니다. 따라서 일반적인 WHERE 조건과 매우 유사하게 작동합니다. 그냥 사용 has('relation')
하면이 관계에서 하나 이상의 관련 모델이있는 모델 만 가져 오기를 의미합니다.
예:
User > hasMany > Post
$users = User::has('posts')->get();
// only users that have at least one post are contained in the collection
whereHas()
기본적으로 동일하게 작동 has()
하지만 관련 모델에서 확인할 추가 필터를 지정할 수 있습니다.
예:
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
게시물을 쿼리 할 때 사용자 관계에 사용하십시오.
whereHas
그것을 사용하는 use Illuminate\Database\Eloquent\Builder;
다음과입니다 function(Builder $query)
. 내가 본 대부분의 예제는 dot을 사용 Builder
하고 $ query를 전달하면 올바른 방법입니까?
문서 에서 이미 사용법을 설명했습니다. 그래서 나는이 방법들을 설명하기 위해 SQL을 사용하고 있습니다.
Order (orders)
많은 것이 있다고 가정합니다 OrderItem (order_items)
.
그리고 당신은 이미 그들 사이의 관계를 구축했습니다.
// App\Models\Order:
public function orderItems() {
return $this->hasMany('App\Models\OrderItem', 'order_id', 'id');
}
이 세 가지 방법은 모두 관계를 기반으로합니다 .
결과 : with()
모델 객체와 관련 결과를 반환합니다.
장점 : 그것은이다 열망 로딩 할 수 N + 1 문제를 방지 .
다음 Eloquent Builder를 사용하는 경우 :
Order::with('orderItems')->get();
라 라벨은이 코드를 두 개의 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...);
그리고 laravel 은 외래 키에 의한 첫 번째 SQL의 결과 와 다른 두 번째 SQL의 결과를 병합 합니다 . 마지막으로 수집 결과를 반환합니다.
따라서 foreign_key가없는 열을 선택하면 관계 결과가 비어 있습니다.
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
관계가 비어 있지 않은 모델의 객체를 반환합니다 .
Order::has('orderItems')->get();
라 라벨은이 코드를 하나의 SQL로 변경합니다 :
select * from `orders` where exists (
select * from `order_items` where `order`.`id` = `order_item`.`order_id`
)
whereHas
및 orWhereHas
방법을 넣어 where
당신에 조건을 has
쿼리. 이 메소드를 사용하면 사용자 정의 제한 조건을 관계 제한 조건에 추가 할 수 있습니다 .
Order::whereHas('orderItems', function($query) {
$query->where('status', 1);
})->get();
라 라벨은이 코드를 하나의 SQL로 변경합니다 :
select * from `orders` where exists (
select *
from `order_items`
where `orders`.`id` = `order_items`.`order_id` and `status` = 1
)
with('relation')
반환 된 컬렉션의 관련 테이블의 데이터가 포함됩니다,has('relation')
그리고whereHas('relation')
것 없는 관련 테이블의 데이터가 포함됩니다. 당신은 모두를 호출 할 필요가 있습니다 그래서with('relation')
뿐만 아니라has()
나whereHas()
.