Implement Propable trait in Brand, Category, Product, and Tenant models to manage properties; remove unused code in Tenant model.

This commit is contained in:
2026-06-22 12:21:30 -03:00
parent 93ebb0a110
commit 894f2a68de
5 changed files with 102 additions and 31 deletions

View File

@@ -2,10 +2,12 @@
namespace App\Domains\Product\Models;
use App\Domains\Prop\Concerns\Propable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Brand extends Model
{
use HasFactory;
use Propable;
}

View File

@@ -2,10 +2,12 @@
namespace App\Domains\Product\Models;
use App\Domains\Prop\Concerns\Propable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
use HasFactory;
use Propable;
}

View File

@@ -2,6 +2,7 @@
namespace App\Domains\Product\Models;
use App\Domains\Prop\Concerns\Propable;
use App\Domains\Tenant\Models\Tenant;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
@@ -19,6 +20,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Product extends Model
{
use HasFactory;
use Propable;
protected $table = 'productos';

View File

@@ -0,0 +1,94 @@
<?php
namespace App\Domains\Prop\Concerns;
use App\Domains\Prop\Models\ModelPropValue;
use App\Domains\Prop\Models\Prop;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use LogicException;
trait Propable
{
/**
* @param array<string, mixed> $attributes
*/
public static function createProp(array $attributes): Prop
{
return Prop::query()->create([
...$attributes,
'propable_type' => static::class,
]);
}
/**
* @return Builder<Prop>
*/
public function props(): Builder
{
return Prop::query()->forModel(static::class);
}
/**
* @return HasMany<ModelPropValue, $this>
*/
public function propValues(): HasMany
{
return $this->hasMany(ModelPropValue::class, 'valuable_id')
->whereHas('prop', fn (Builder $query) => $query->forModel(static::class));
}
public function getPropValue(Prop|string $prop): ?ModelPropValue
{
$resolvedProp = $this->resolveProp($prop);
return $this->propValues()
->where('prop_id', $resolvedProp->getKey())
->first();
}
public function setPropValue(Prop|string $prop, mixed $value): ModelPropValue
{
$this->ensurePropValuesCanBeManaged();
$resolvedProp = $this->resolveProp($prop);
return $this->propValues()->updateOrCreate(
['prop_id' => $resolvedProp->getKey()],
['value' => $value],
);
}
public function deletePropValue(Prop|string $prop): bool
{
$resolvedProp = $this->resolveProp($prop);
return $this->propValues()
->where('prop_id', $resolvedProp->getKey())
->delete() > 0;
}
protected function ensurePropValuesCanBeManaged(): void
{
if (! $this->exists) {
throw new LogicException('Cannot manage prop values for an unsaved model.');
}
}
protected function resolveProp(Prop|string $prop): Prop
{
if ($prop instanceof Prop) {
if ($prop->propable_type !== static::class) {
throw new LogicException('The given prop does not belong to this model type.');
}
return $prop;
}
return Prop::query()
->forModel(static::class)
->where('codigo', $prop)
->firstOrFail();
}
}

View File

@@ -2,14 +2,11 @@
namespace App\Domains\Tenant\Models;
use App\Domains\Prop\Models\ModelPropValue;
use App\Domains\Prop\Models\Prop;
use App\Domains\Prop\Concerns\Propable;
use App\Domains\Product\Models\Product;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
#[Fillable([
@@ -20,6 +17,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
class Tenant extends Model
{
use HasFactory;
use Propable;
/**
* @return HasMany<Product, $this>
@@ -28,31 +26,4 @@ class Tenant extends Model
{
return $this->hasMany(Product::class, 'tenant_codigo', 'codigo');
}
/**
* @return BelongsToMany<TenantProp, $this>
*/
public function tenantProps(): BelongsToMany
{
return $this->belongsToMany(TenantProp::class, 'tenant_prop_definitions', 'tenant_codigo', 'prop_codigo', 'codigo', 'codigo')
->withPivot('valor')
->withTimestamps();
}
/**
* @return Builder<Prop>
*/
public function props(): Builder
{
return Prop::query()->forModel(static::class);
}
/**
* @return HasMany<ModelPropValue, $this>
*/
public function propValues(): HasMany
{
return $this->hasMany(ModelPropValue::class, 'valuable_id')
->whereHas('prop', fn (Builder $query) => $query->forModel(static::class));
}
}