Všimněte si, že způsob, jakým se to pokoušíte udělat, můžete získat více řádků na položku (jednou na související záznam). Lepším způsobem by bylo mít řadu výpisů na položku.
Pokud používáte výmluvné modely a máte správně nastavené vztahy, můžete zkusit následující:
$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();
Nyní by každá položka měla mít listings
vlastnictví. Například pro první položku můžete přistupovat k výpisům následujícím způsobem:
$item1 = $items[0];
$listings1 = $item1->listings;
Všimněte si, že whereHas()
pravděpodobně vytvoří korelovaný EXISTS
dílčí dotaz pro každý záznam v $cats
pole. Pokud je to pomalé, můžete použít dotaz JOIN jako:
$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();
Pokud nepoužíváte výmluvnost, můžete „netrpělivé načítání“ provést také sami.
$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');
}