Перенос красноречивой модели в другой класс приводит к превышению вложенности - PullRequest
0 голосов
/ 19 апреля 2020

Я использую Laravel 5.5. Я написал оболочку, которая берет модель Eloquent и переносит ее в класс Entity, и у каждой модели есть собственная оболочка. Предположим, у пользователя много продуктов, а продукт принадлежит одному пользователю. При упаковке мне нужно получить продукты пользователя и передать их в оболочку продукта, чтобы обернуть их в сущности продукта. В оболочке продукта мне нужно, чтобы пользователь-владелец этого продукта связал его с сущностью пользователя. Итак, еще раз, в пользовательской оболочке мне нужны продукты пользователя !, и это создает бесконечное l oop.

EntityWrapper:

abstract class EntityWrapper
{
    protected $collection;
    protected $entityClass;
    public $entity;

    public function __construct($collection)
    {
        $this->collection = $collection;
        $this->entity = $this->buildEntity();
    }

    protected function buildEntity()
    {
        $tempEntity = new $this->entityClass;

        $Entities = collect([]);

        foreach ($this->collection as $model) {
            $Entities->push($this->makeEntity($tempEntity, $model));
        }

        return $Entities;
    }

    abstract protected function makeEntity($entity, $model);
}

UserEntityWrapper:

class UserEntityWrapper extends EntityWrapper
{
    protected $entityClass = UserEntity::class;

    protected function makeEntity($userEntity, $model)
    {
        $userEntity->setId($model->user_id);
        $userEntity->setName($model->name);

        // set other properties of user entity...

        //--------------- relations -----------------
        $userEntity->setProducts((new ProductEntityWrapper($model->products))->entity);

        return $userEntity;
    }
}

ProductEntityWrapper:

class ProductEntityWrapper extends EntityWrapper
{
    protected $entityClass = ProductEntity::class;

    protected function makeEntity($productEntity, $model)
    {
        $productEntity->setId($model->product_id);
        $productEntity->setName($model->name);

        // set other properties of product entity...

        //--------------- relations -----------------
        $productEntity->setUser((new UserEntityWrapper($model->user))->entity);

        return $productEntity;
    }
}

UserEntity:

class UserEntity
{
    private $id;
    private $name;
    private $products;
    //... other properties

    public function setProducts($products)
    {
         $this->products = $products;
    }

    // other getters and setters...
}

Когда я Чтобы получить пользовательские сущности путем вызова (new UserEntityWrapper(User::all()))->entity, это вызывает бесконечное l oop. Итак, как я могу предотвратить вложенный вызов отношений между моделями? Спасибо за любое предложение.

1 Ответ

0 голосов
/ 27 апреля 2020

Наконец я нашел решение. Как и в каждом классе-обертке, я использовал свойство dynamici c для получения коллекции отношений, в дополнение к наложению дополнительных запросов, это вызывает ленивую загрузку. Таким образом, перед передачей коллекции моделей в каждую оболочку извлекается необходимая модель отношений, и каждая оболочка сначала проверяет наличие отношений с помощью метода getRelations() (который возвращает массив доступных отношений). Если предполагаемые отношения доступны, коллекция моделей отношений передается в соответствующий класс-оболочку.

UserEntityWrapper:

class UserEntityWrapper extends EntityWrapper
{
    protected $entityClass = UserEntity::class;

    protected function makeEntity($userEntity, $model)
    {
        $userEntity->setId($model->user_id);
        $userEntity->setName($model->name);

        // set other properties of user entity...

        //--------------- relations -----------------
        $relations = $model->getRelations();

        $products = $relations['products'] ?? null;
        if ($products) {
            $userEntity->setProducts((new ProductEntityWrapper($products))->entity);
        }

        return $userEntity;
    }
}

И аналогичная функциональность используется для другие обертки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...