Assuming I have the following MySQL tables to represent pricebooks, items and the relationship between them:
item - item_id|name|...etc
pricebook - pricebook_id|name|...etc
and the following pivot table
pricebook_item - pricebook_id|item_id|price|...etc
I have the correlating Eloquent models: Pricebook
, Item
and a repository named PricebookData
to retrieve the necessary information.
Within the PricebookData
repository, I need to get the pricebook data grouped by pricebook id and then keyed by item_id for easy access on client side.
If I do:
Pricebook::all()->groupBy('pricebook_id');
I get the information grouped by the pricebook_id
but inside each pricebook the keys are simple numeric index (it arrives as js array) and not the actual product_id. So when returning to client side Javascript, the result arrives as the following:
pricebookData: {1: [{}, {}, {}...], 2: [{}, {}, {}...]}
The problem with the prices arriving as array, is that I can not access it easily without iterating the array. Ideally I would be able to receive it as:
pricebookData: {1: {1001:{}, 1002: {}, 1003: {}}, 2: {1001:{}, 1002: {}, 1003: {}}}
//where 1001, 1002, 1003 are actual item ids
//with this result format, I could simply do var price = pricebookData[1][1001]
I've also tried the following but without success:
Pricebook::all()->keyBy('item_id')->groupBy('pricebook_id');
The equivalent of what I am trying to avoid is:
$prices = Pricebook::all();
$priceData = [];
foreach ($prices as $price)
{
if (!isset($priceData[$price->pricebook_id]))
{
$priceData[$price->pricebook_id] = [];
}
$priceData[$price->pricebook_id][$price->item_id] = $price;
}
return $priceData;
I am trying to find a pure elegant Eloquent/Query Builder solution.
The whereBetween() method is a query builder chained alongside other Laravel query builders used to fetch data from the database. The whereBetween() method queries the database table to fetch rows of records from the database within a range of values.
The Laravel Eloquent first() method will help us to return the first record found from the database while the Laravel Eloquent firstOrFail() will abort if no record is found in your query. So if you need to abort the process if no record is found you need the firstOrFail() method on Laravel Eloquent.
Laravel Pluck() is a Laravel Collections method used to extract certain values from the collection. You might often would want to extract certain data from the collection i.e Eloquent collection.
I think what you want is
Pricebook::all()
->groupBy('pricebook_id')
->map(function ($pb) { return $pb->keyBy('item_id'); });
You first group by Pricebook, then each Pricebook subset is keyed by item_id. You were on the right track with
Pricebook::all()->keyBy('item_id')->groupBy('pricebook_id');
unfortunately, as it is implemented, the groupBy
resets previous keys.
Pricebook::all()->keyBy('item_id')->groupBy('pricebook_id', true);
(groupBy
second parameter $preserveKeys
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With