Bemærk, at den måde, du prøver at gøre det på, kan få flere rækker pr. element (én gang pr. relateret liste). En bedre måde ville være at have en række lister pr. vare.
Hvis du bruger veltalende modeller, og du har opsat relationerne korrekt, kan du prøve følgende:
$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();
Nu skal hvert element have en listings
ejendom. For eksempel for det første emne kan du få adgang til fortegnelserne på følgende måde:
$item1 = $items[0];
$listings1 = $item1->listings;
Bemærk, at whereHas()
vil sandsynligvis skabe en korreleret EXISTS
underforespørgsel for hver post i $cats
array. Hvis det er for langsomt, kan du bruge en JOIN-forespørgsel som:
$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();
Hvis du ikke bruger veltalende, kan du også selv klare den "ivrige læsning".
$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');
}