1
votes

I have two Laravel Eloquent models, Product and ProductCategory with a belongsTo() relationship named Category() from Product to ProductCategory.

I already have the model collection iterating through a @foreach loop in a display blade but would like to be able to get a count of the number of products based on the Category() relationship...

IE: In a result set of 20 models in the collection there may be 5 Motors, 5 Gearboxes, and 5 Acme Widgets. I am trying to find a way to output a list of the categories returned as part of the results and how many record relate to each returned category.

Product Model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model {
/**
 * The table associated with the model.
 *
 * @var string
 */
protected $table = 'products';


/**
 * The primary key associated with the table.
 *
 * @var string
 */
protected $primaryKey = 'id';


/**
 * Indicates if the IDs are auto-incrementing.
 *
 * @var bool
 */
public $incrementing = true;


/**
 * All related features for the current model.
 */
public function features() {
    return $this->hasMany('App\ProductFeature');
}


/**
 * Created By Relationship
 */
public function created_by() {
    return $this->belongsTo('App\User');
}


/**
 * Modified By Relationship.
 */
public function modified_by() {
    return $this->belongsTo('App\User');
}


/**
 * Category Relationship.
 */
public function category() {
    return $this->belongsTo('App\ProductCategory', 'category_id', 'id');
}





/**
 * Images Relationship.
 */
public function images() {
    return $this->HasMany('App\ProductImage', 'product_id', 'id');
}


/**
 * The relations to eager load on every query.
 *
 * @var array
 */
protected $with = ['features', 'created_by', 'modified_by', 'images'];
}

ProductCategory Model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class ProductCategory extends Model {
/**
 * The table associated with the model.
 *
 * @var string
 */
protected $table = 'product_categories';


/**
 * The primary key associated with the table.
 *
 * @var string
 */
protected $primaryKey = 'id';


/**
 * Indicates if the IDs are auto-incrementing.
 *
 * @var bool
 */
public $incrementing = true;


/**
 * All related features for the current model.
 */
public function products() {
    return $this->hasMany('App\Product', 'category_id', 'id');
}


/**
 * Created By Relationship
 */
public function created_by() {
    return $this->belongsTo('App\User');
}


/**
 * Modified By Relationship.
 */
public function modified_by() {
    return $this->belongsTo('App\User');
}

}

Controller Method

public function showCategory($catAlias) {
    $products= Product::all();

    return view("website.store.results", ["products" => $products]);
}

Example Output Desired

Category | Count
=================
Cat 1    |   4
Cat 2    |   1
Cat 5    |   5
1
where is your controller code that is sending data to the view?lagbox
@lagbox - I have added the controller method which sends the data to the view.Chris Rutherfurd
so you just want a count of how many products are in this one category? im kinda confusedlagbox
The returned result set may have all products from a single category or may return products from multiple categories. I want to show a list in the view of each category in the returned collection and how many records are associated with each individual category. I have added an additional update to give you an idea of what i want to end up with being returned to the blade.Chris Rutherfurd
Sorry wrong part of the code I have updated the question above to reflect the correct code.Chris Rutherfurd

1 Answers

1
votes

You probably want to be returning Categories not Products. You can eager load the count of the relationship with the method withCount:

public function someMethod()
{
    return view('someview', [
        'categories' => Category::withCount('products')->get(),
    ]);
}

@foreach ($categories as $category)
  <tr>
    <td>{{ $category->name }}</td>
    <td>{{ $category->products_count }}</td>
  </tr>
@endforeach

Laravel 6.x Docs - Eloquent - Relationships - Counting Related Models withCount

I wouldn't be returning all products in one go, but if you did you could group them by category_id then do a count, if you had to.

return view('someview', [
    'products' => Product::with('category:id,name')->get(),
]);

Then in the side where you need the count:

@foreach ($products->groupBy('category_id') as $group)
  <tr>
    <td>{{ $group->first()->category->name }}</td>
    <td>{{ $group->count() }}</td>
  </tr>
@endforeach

Or you can return your products query and have another query that does the categories with their count.