あなたがそれをしようとしている方法では、アイテムごとに複数の行を取得する可能性があることに注意してください(関連するリストごとに1回)。より良い方法は、アイテムごとに一連のリストを作成することです。
雄弁なモデルを使用していて、関係を正しく設定している場合は、次のことを試すことができます。
$cats = [1, 2, 3];
$query = Item::with('listings');
foreach ($cats as $cat) {
$query->whereHas('catitems', function($q) use($cat) {
$q->where('id', $cat);
});
}
$items = $query->get();
これで、すべてのアイテムにlistings
が表示されます。 財産。たとえば、最初のアイテムについては、次の方法でリストにアクセスできます。
$item1 = $items[0];
$listings1 = $item1->listings;
whereHas()
に注意してください おそらく相関するEXISTS
を作成します $cats
のすべてのエントリのサブクエリ 配列。それが遅くなる場合は、次のようなJOINクエリを使用できます:
$items = Item::with('listings')
->join('catitem_item', 'catitem_item.item_id', '=', 'items.id')
->whereIn('catitem_item.catitem_id', $cats)
->groupBy('items.id')
->having(DB::raw('count(*)'), '=', count($cats))
->select('items.*')
->get();
雄弁に使用しない場合は、自分で「積極的な読み込み」を行うこともできます。
$items = DB::table('items')
->join('catitem_item', 'catitem_item.item_id', '=', 'items.id')
->whereIn('catitem_item.catitem_id', $cats)
->groupBy('items.id')
->having(DB::raw('count(*)'), '=', count($cats))
->select('items.*')
->get()
->keyBy('id');
foreach ($items as $item) {
$item->listings = [];
}
$itemIds = $items->pluck('id');
$listings = DB::table('listings')
->join('item_listing', 'item_listing.listing_id', '=', 'listings.id')
->whereIn('item_listing.item_id', $itemIds)
->groupBy('listings.id')
->select('listings.*', DB::raw('group_concat(item_listing.item_id) as item_ids'))
->get();
foreach ($listings as $listing) {
$itemIds = explode(',', $listing->item_ids);
foreach ($itemIds as $itemId) {
$items[$itemId]->listings[] = $listing;
}
$listing->forget('item_ids');
}