withCount morph through?
I have the following setup: Products has many items/variations, items has many inventories, and an inventory belongs to a morph (stockable which is a warehouse or a store), and the stockable (warehouse or store) belongs to 1 a region.
Maybe I am making this complicated, but I am trying to see how many regions a product is in and return for example: "Coding Product 1 is in 5 regions", so it returns the count of regions for each product.
I have setup a has Many through (Inventory::class, Item::class) on the Product to get the inventories for example $product->inventories. This is the part where I am stuck. If I $product->inventories->first()->stockable->region->id, gives me the region->id. This seems inefficient, and I was hoping I could deploy a has one through, but the inventory contains the stockable morphto relationship...
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
use HasFactory;
public function items()
{
return $this->hasMany(Item::class);
}
public function inventories()
{
return $this->hasManyThrough(Inventory::class, Item::class);
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Item extends Model
{
use HasFactory;
public function inventories()
{
return $this->hasMany(Inventory::class);
}
public function product()
{
return $this->belongsTo(Product::class);
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Lukeraymonddowning\Mula\Facades\Mula;
class Inventory extends Model
{
use HasFactory;
public function stockable()
{
return $this->morphTo();
}
public function item()
{
return $this->belongsTo(Item::class);
}
public function getValueAttribute()
{
return $this->quantity * $this->item->price;
}
public function getFormattedValueAttribute()
{
return Mula::parse($this->value, 'USD')->display();
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Lukeraymonddowning\Mula\Facades\Mula;
class Store extends Model
{
use HasFactory;
public function region()
{
return $this->belongsTo(Region::class);
}
public function itemInventory()
{
return $this->morphMany(Inventory::class, 'stockable');
}
public function getInventoryValueAttribute()
{
$total = 0;
foreach($this->itemInventory as $inventory) {
$total += $inventory->value;
}
return $total;
}
public function getFormattedInventoryValueAttribute()
{
return Mula::parse($this->inventory_value, 'USD')->display();
}
}
Here is the query i'm currently building:
$products = Product::when($this->searchProducts != '', function($query) {
$query->where('title', 'like', '%'.$this->searchProducts.'%');
})->withCount(['items', 'inventories as store_count' => function($query) {
$query->where('stockable_type', 'App\Models\Store');
}, 'inventories as warehouse_count' => function($query) {
$query->where('stockable_type', 'App\Models\Warehouse');
}])->withAvg('items', 'price')->withAvg(['inventories as store_avg_quantity' => function($query) {
$query->where('stockable_type', 'App\Models\Store');
}, 'inventories as warehouse_avg_quantity' => function($query) {
$query->where('stockable_type', 'App\Models\Warehouse');
}], 'quantity')->withSum(['inventories as store_quantity' => function($query) {
$query->where('stockable_type', 'App\Models\Store');
}, 'inventories as warehouse_quantity' => function($query) {
$query->where('stockable_type', 'App\Models\Warehouse');
}, 'inventories as total_quantity'], 'quantity')->when($this->sortQuantity == true, function($query) {
$query->orderBy('total_quantity', $this->sortDirection ? 'asc' : 'desc' );
})->get();
I want to add withCount and get regions_count
any tips?
Please or to participate in this conversation.