menashe's avatar

Return Object rather than Array of stdout

I use the following code to return an Eloquent ORM, including the latest price per item.

    $purchases = Purchase::with([
        'packaging',
        'packaging.item',
        'packaging.item.manufacturer',
        'packaging.item.brand',
        'packaging.unit',
        'packaging.price' => function ($query) use ($shopping_date) {

            $query->select(DB::raw('DISTINCT ON(packaging_id) *'))
                ->where('date', '<=', $shopping_date)
                ->orderBy('packaging_id', 'asc')
                ->orderBy('date', 'desc');
        }
    ])->where('shopping_id', '=', $id)->get();

Because of the raw DB, the resulting single 'price' object is returned as an array.

[ { key1: value1, key2: value2, ... packaging: { ... price: [ { ... } ] } }]

I have tried everything I could think of using pure Eloquent--latest() and latestOfMany()--but they all appear to find the latest before filtering by date.

I have written a JavaScript routine that traverse the returned collection and replaces the array of object with the object itself. But it does seem like the "clean" way to accomplish this.

Is there any way to return the price as a simple object or--at worst--some PHP code to clean up the 'purchases' collection before it is returned?

0 likes
3 replies
JakeMiller's avatar

You can clean up the purchases collection in PHP by mapping over it before returning. For example, loop through each purchase and, if the price array exists, replace it with the first object in the array. This way, the price is returned as a simple object and you don’t need to handle it separately in JavaScript.

menashe's avatar

Thank you! Exactly what I wanted to try, but it did not modify the collection.

Am I doing it wrong?

    $purchases = $purchases->map(function ($purchase) {
        Debugbar::info($purchase->packaging->price);
        if ($purchase->packaging->price) {
            $purchase->packaging->price = (object) $purchase->packaging->price;
        }
        
        return $purchase;
    });
krisi_gjika's avatar

can you show an example of your dataset, and what are you trying to query from it? What is the resulting response you expect? What do you mean by "they all appear to find the latest before filtering by date"? Why do you need "->select(DB::raw('DISTINCT ON(packaging_id) *'))"?

Please or to participate in this conversation.