mafortis
mafortis

Reputation: 7128

Laravel resource groupby the result

I have resource API that gives me the result but I want to group them based on relationship model.

Code

controller

$outlet = Outlet::where('slug', $slug)->with(['barcodes.product', 'damages', 'images'])->first();

result

{
    "data": {
        "id": 1,
        "name": "Outlet One",
        "slug": "outlet-one",
        "address": "Jl Raya Bogor No.200",
        "cover": null,
        "phone": "0211111112",
        "products": [
            {
                "id": 1,
                "sku": "AB001SU",
                "serial_number": 5245412185,
                "price": 120000,
                "discount": null,
                "product": {
                    "id": 1,
                    "name": "Product One",
                    "slug": "product-one",
                    "stock": "70",
                    "cover": null,
                    "description": "This is first product description.",
                    "sku": "AB001SU",
                    "price": 120000,
                    "discount": null
                }
            },
            {
                "id": 2,
                "sku": "FD51",
                "serial_number": 778516,
                "price": 75300,
                "discount": 5300,
                "product": {
                    "id": 1,
                    "name": "Product One",
                    "slug": "product-one",
                    "stock": "70",
                    "cover": null,
                    "description": "This is first product description.",
                    "sku": "AB001SU",
                    "price": 120000,
                    "discount": null
                }
            },
            {
                "id": 3,
                "sku": "7609FS",
                "serial_number": 232547544,
                "price": 35900,
                "discount": null,
                "product": {
                    "id": 2,
                    "name": "Product Two",
                    "slug": "product-two",
                    "stock": "120",
                    "cover": null,
                    "description": "This is second product description.",
                    "sku": "FRY8016",
                    "price": 450000,
                    "discount": 50000
                }
            }
        ]
    },
    "message": "Outlet retrieved successfully."
}

As you can see in products": [...] id 1 and 2 are belong to Product One is that possible for me to group by my barcodes.product based on product model?

Update

To be more clear; What I'm looking for is something like this:

{
        "data": {
            "id": 1,
            "name": "Outlet One",
            "slug": "outlet-one",
            "address": "Jl Raya Bogor No.200",
            "cover": null,
            "phone": "0211111112",
            "products": [
                {
                    "id": 1,
                    "name": "Product One",
                    "slug": "product-one",
                    "stock": "70",
                    "cover": null,
                    "description": "This is first product description.",
                    "sku": "AB001SU",
                    "price": 120000,
                    "discount": null
                    "barcodes": {  // now barcodes are grouped by prodcuts
                        "id": 1,
                        "sku": "AB001SU",
                        "serial_number": 5245412185,
                        "price": 120000,
                        "discount": null,
                    },
                    {
                        "id": 2,
                        "sku": "FD51",
                        "serial_number": 778516,
                        "price": 75300,
                        "discount": 5300,
                    },
                },
                {
                    "id": 2,
                    "name": "Product Two",
                    "slug": "product-two",
                    "stock": "120",
                    "cover": null,
                    "description": "This is second product description.",
                    "sku": "FRY8016",
                    "price": 450000,
                    "discount": 50000
                    "barcodes": { // now barcodes are grouped by prodcuts
                        "id": 3,
                        "sku": "7609FS",
                        "serial_number": 232547544,
                        "price": 35900,
                        "discount": null,
                    }
                }
            ]
        },
        "message": "Outlet retrieved successfully."
    }

Update 2

Outlet model

public function barcodes()
{
    return $this->belongsToMany(Barcode::class, 'outlet_products');
}

Barcode model

public function outlets()
{
    return $this->belongsToMany(Outlet::class, 'outlet_products');
}

public function product()
{
    return $this->belongsTo(Product::class);
}

Upvotes: 0

Views: 365

Answers (2)

Shizzen83
Shizzen83

Reputation: 3529

Never tried something like this but you maybe could do this in your Outlet model

use App\Http\Resources\ProductsResource;

public function getProductsAttribute()
{
    $barcodes = $this->barcodes
        ->loadMissing('product')
        ->makeHidden('product');

    $products = $barcodes->pluck('product')->keyBy('id');

    $groupedBarcodes = $barcodes->groupBy(function ($barcode) {
            return $barcode->product->id;
        });

    return ProductsResource::collection($products->map(function ($product, $id) use ($groupedBarcodes) {
        return $product->setAttribute('barcodes', $groupedBarcodes[$id]);
    }))->resolve();
}

What is your resource output with that?

Upvotes: 1

A.A Noman
A.A Noman

Reputation: 5270

In your Outlet Model write this

public function products(){
    return $this->hasMany(Product::class, 'product_id','id');
}

In your Product Model write this

public function barcodes(){
    return $this->hasMany(Barcode::class,'barcode_id','id');
}

Then for your query just write this

$outlet = Outlet::where('slug', $slug)->products()->barcodes()->with(['your_field'])->first();

Upvotes: 0

Related Questions