回答:
with()
以下のためである積極的なロード。つまり、基本的に、メインモデルに沿って、Laravelは指定した関係をプリロードします。これは、モデルのコレクションがあり、すべてのモデルのリレーションをロードする場合に特に役立ちます。積極的なロードでは、コレクション内のすべてのモデルに対して1つではなく、1つの追加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')
する場合は、この関係に少なくとも1つの関連モデルがあるモデルのみを取得することを意味します。
例:
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)
。私が見たほとんどの例、ドットはを使用Builder
し、$ queryを渡すだけです。これは正しい方法ですか?
ドキュメントはすでに使用法を説明しています。だから私はこれらの方法を説明するためにSQLを使用しています
があると仮定すると、Order (orders)
多くがありOrderItem (order_items)
ます。
そして、あなたはすでにそれらの間の関係を構築しています。
// App\Models\Order:
public function orderItems() {
return $this->hasMany('App\Models\OrderItem', 'order_id', 'id');
}
これら3つの方法はすべて、関係に基づいています。
結果: with()
モデルオブジェクトとその関連結果を返します。
利点:それは熱心ローディングできるN + 1つの問題を防ぎます。
次のEloquent Builderを使用している場合:
Order::with('orderItems')->get();
Laravelはこのコードを2つの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();
Laravelはこのコードを1つの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();
Laravelはこのコードを1つの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()
。