Laravel - Реализовать модель фабрики проектирования шаблонов - PullRequest
0 голосов
/ 02 апреля 2019

Я пытаюсь реализовать шаблон 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 дБ запросов, чтобы создать экземпляр объекта.Есть ли лучший подход для этого?Если нет, есть ли способ сделать это только одним запросом?

...