Как преобразовать или привести красноречивую модель к одному из ее дочерних элементов на основе значения отношения родительского типа - PullRequest
0 голосов
/ 07 июня 2019

У меня есть таблица room с внешним ключом room_type_id к таблице room_type.

У меня есть соответствующие модели в Laravel, а также некоторые дочерние классы для разных комнат:

class RoomType extends Model
{
    //
}

class Room extends Model
{
    protected $with = ['roomType'];

    public function roomType()
    {
        return $this->belongsTo('RoomType', 'room_type_id');
    }
}

class Bedroom extends Room
{
    protected static function boot()
    {
        parent::boot();

        static::addGlobalScope('type', function (Builder $builder) {
            $builder->whereHas('roomType', function ($query) {
                $query->where('code', 'like', 'BEDROOM');
            });
        });
    }
}

class Kitchen extends Room
{
    protected static function boot()
    {
        parent::boot();

        static::addGlobalScope('type', function (Builder $builder) {
            $builder->whereHas('roomType', function ($query) {
                $query->where('code', 'like', 'KITCHEN');
            });
        });
    }
}

Я пытаюсь при запросе room вернуть дочерний элемент (bedroom или kitchen) в зависимости от типа.

Что яЯ делаю прямо сейчас:

$results = Room::where('...')->get();
foreach ($results as $key => $record) {
    switch ($record->roomType->code) {
        case 'BEDROOM':
            $results{$key} = (new Bedroom)
            ->newInstance([], true)
            ->setRawAttributes($record->getAttributes());
            break;
        case 'KITCHEN':
            $results{$key} = (new Kitchen)
            ->newInstance([], true)
            ->setRawAttributes($record->getAttributes());
            break;
    }
}
// returns a Collection of `Bedroom` and `Kitchen` models

Мне не нравится, что мне нужно создать каждую модель с setRawAttributes(), плюс мне нужно было бы добавить все загруженные отношения обратно, плюс япотерять исходные атрибуты, если они мне понадобятся, ну, просто я выгляжу неправильно, как я это делаю.

Я бы хотел добиться того же запроса, чтобы тот же запрос возвращал коллекцию дочерних моделей на основе ее roomType-> значение отношения кода:

$results = Room::where('...')->get();
// returns a Collection of `Room` (shocker!)
// i want a Collection of `Bedroom` and 'Kitchen`

Я думал, что могу как-то использовать полиморфизм и morphMap, но не могу заставить его работать, у меня нет типичных полиморфных отношений.

Любойпомощь или подсказка будет тепло приветствоваться.

...