0
votes

I have Products, Attributes and Categories. I want to create custom attributes array without using foreach. I know I can get that done with foreach but I want to do it with Eloquent query.

This is my table diagram: Attributes tables diagram

I want to create array (Eloquent returned Object) like this:

$attributes = [
        'attribute1' => [
            'attribute1_property1' => 'attribute1_property1_count_in_all_products',
            'attribute1_property2' => 'attribute1_property2_count_in_all_products',
            'attribute1_property3' => 'attribute1_property3_count_in_all_products',
        ],
        'attribute2' => [
            'attribute2_property1' => 'attribute1_property1_count_in_all_products',
            'attribute2_property2' => 'attribute1_property2_count_in_all_products',
            'attribute2_property3' => 'attribute1_property3_count_in_all_products',
        ],
        ...
    ]

I have models Product, Attribute, AttributeProperty.

Product::whereHas('categories', function ($q) use ($catId) {
        $q->whereId($catId);
    })->with('attributeProperties.attribute')->get();

With above code I get list of products and it's attribute options but I want that attribute options grouped by parent attribute and counted how many products had that attribute option.

In other words I want to get all attribute_options grouped by parent attribute and counted how many products do that attribute_option have on this category. Thank you in advance.

1
Call toArray() on the sub collection?Jeremy Harris
No That's not the case. I want to get array hirarchy like that in above code.Buglinjo
For AttributeOption I'm not seeing attribute_options in the schema?Eric Tucker
Sorry, I have edited my question it was AttributePropertyBuglinjo

1 Answers

1
votes

Is there any specific reason you are querying the Product model? If that's not needed and you're just after the example array you can do it like:

$results = Attribute::with(['attributeProperties' => function($query) {
    return $query->withCount('products');
}])->get();

You can access what you want through the collections (I'm taking the first item of each just for reference):

$attribute = $results->first();
$attributeProperty = $attribute->attributeProperties->first();
$attributeProperty->products_count;

OR if you need it in that EXACT format you can map the results like:

$results->keyBy('display_name')->map(function($attribute) {
    return $attribute->attributeProperties
        ->keyBy('display_name')
        ->map(function($property) {
            return $poperty->products_count;
        })
        ->toArray();
})
->toArray();