Я пытаюсь реализовать шаблон Factory Design с моделью Laravel.У меня есть модель вознаграждения, которая может иметь (на данный момент) два типа: вознаграждение за очки или вознаграждение за кешбэк.
У меня есть класс вознаграждения со всем
class Reward extends Model
{
// class Reward stuff
}
И я также сделал дваклассы, расширяющие Reward (оба из них с globalScope, ссылающимся на его тип), PointsReward:
class PointsReward extends Reward
{
protected $table = "rewards";
protected static function boot()
{
parent::boot();
static::addGlobalScope(
'points',
function (Builder $builder) {
$builder->whereHas(
'rewardType',
function ($subQuery) {
$subQuery->where('type', 'Points');
}
);
}
);
}
}
и CashbackReward:
class CashbackReward extends Reward
{
protected $table = "rewards";
protected static function boot()
{
parent::boot();
static::addGlobalScope(
'cashback',
function (Builder $builder) {
$builder->whereHas(
'rewardType',
function ($subQuery) {
$subQuery->where('type', 'Points');
}
);
}
);
}
}
Теперь я пытался создать класс Factory:
class RewardFactory
{
const CASHBACK_REWARD = 0;
const POINTS_REWARD = 1;
static function create(int $rewardType, array $data)
{
switch($rewardType){
case self::CASHBACK_REWARD:
return CashbackReward::create($data);
break;
case self::POINTS_REWARD:
return PointsReward::create($data);
break;
default:
throw new Exception("Not supported");
}
}
static function find(int $id) : Reward
{
$main = Reward::find($id);
switch($main->rewardType->type){
case 'Points':
return PointsReward::find($id);
break;
case 'Cashback':
return CashbackReward::find($id);
break;
default:
throw new Exception("Not supported");
return null;
}
}
}
Моя проблема связана с методом поиска.Его цель - найти вознаграждение по идентификатору (как метод Laravel) и вернуть объект в зависимости от его свойства rewardType->type
.
Конечно, это работает, но мне нужно сделать 2 дБ запросов, чтобы создать экземпляр объекта.Есть ли лучший подход для этого?Если нет, есть ли способ сделать это только одним запросом?