Наследование доктрины: обновление полей сущностей - PullRequest
0 голосов
/ 25 сентября 2018

Я пытаюсь использовать InheritanceType ("JOINED") для некоторых объектов API.Кажется, все работает правильно, пока я не пытаюсь реализовать свою процедуру обновления.

У меня есть следующие классы: Абстрактный класс Item с абстрактными подклассами ItemA, ItemB и так далее.Эти классы имеют подклассы SubItemA, SubItemB и т. Д.

В зависимости от класса объекта, я должен иметь возможность обновлять различные поля, поскольку не все дочерние классы имеют одинаковые поля.Для этого у меня есть одна форма на каждый детский класс.Это моя функция:

public function update(Request $request, $itemId): JsonResponse
{
    $data = json_decode($request->getContent(), true);

    $item = $this->entityManager->getRepository(Item::class)->findOneBy(['id' => $itemId]);

    // ... Error Handling ...

    // Get the form of the item child class
    $itemType = get_class($item);
    $formClass = null;
    switch ($itemType) {
        case 'SubItemA':
            $formClass = SubItemAType::class;
            break;
        case 'SubItemB':
            $formClass = SubItemBType::class;
            break;
        // ... Other Item Types ...
    }

    $form = $this->createForm($formClass, $item);

    $form->submit($data);

    // ... Error Handling ...

    $this->entityManager->persist($item);
    $this->entityManager->flush();
}

При использовании этой функции я могу обновить все поля, унаследованные от класса Item.Но поля, которые существуют только в классе SubItemA, не сохраняются в базе данных, даже если get_class($item) возвращает SubItemA, что заставляет меня думать, что объект следует рассматривать как SubItemA вместо Item.

В целях тестирования я создал отдельный репозиторий для своего класса SubItemA и изменил мой getRepository вызов для извлечения этого репозитория:

public function update(Request $request, $itemId): JsonResponse
{
    $data = json_decode($request->getContent(), true);

    $item = $this->entityManager->getRepository(SubItemA::class)->findOneBy(['id' => $itemId]);

    // ... Error Handling ...

    // Get the form of the item child class
    $itemType = get_class($item);
    $formClass = null;
    switch ($itemType) {
        case 'SubItemA':
            $formClass = SubItemAType::class;
            break;
        case 'SubItemB':
            $formClass = SubItemBType::class;
            break;
        // ... Other Item Types ...
    }

    $form = $this->createForm($formClass, $item);

    $form->submit($data);

    // ... Error Handling ...

    $this->entityManager->persist($item);
    $this->entityManager->flush();
}

Используя этот код, я могу обновить все поля сущности,даже те, которые определены только в классе SubItemA.Но, конечно, этот код не будет работать для сущностей типа SubItemB и так далее.Чтобы это работало динамически со всеми моими дочерними типами, я попробовал следующее:

public function update(Request $request, $itemId): JsonResponse
{
    $data = json_decode($request->getContent(), true);

    $item_tmp = $this->entityManager->getRepository(Item::class)->findOneBy(['id' => $itemId]);
    $item = $this->entityManager->getRepository(get_class($item_tmp))->findOneBy(['id' => $itemId]);

    // ... Error Handling ...

    // Get the form of the item child class
    $itemType = get_class($item);
    $formClass = null;
    switch ($itemType) {
        case 'SubItemA':
            $formClass = SubItemAType::class;
            break;
        case 'SubItemB':
            $formClass = SubItemBType::class;
            break;
        // ... Other Item Types ...
    }

    $form = $this->createForm($formClass, $item);

    $form->submit($data);

    // ... Error Handling ...

    $this->entityManager->persist($item);
    $this->entityManager->flush();
}

Я понимаю, что этот код вводит накладные расходы, выбирая одну и ту же сущность дважды.Но, к сожалению, это даже не работает.Опять же, обновляются только поля из класса Item.Кажется, что после загрузки сущности в первый раз она кэшируется и каким-то образом связывается с репозиторием Item, что не позволяет мне на самом деле повторно извлечь ее через мой репозиторий SubItemA.

Я неЯ не достаточно разбираюсь во внутренней работе Учения, чтобы понять, что здесь происходит.Каков рекомендуемый способ обновления?Нужны ли разные точки API для всех моих дочерних классов?


Edit Я только что понял, что если я изменю свой "промежуточный" абстрактный класс ItemA, чтобы он не былабстрактный, все работает правильно с первым кодом.Таким образом, абстрактный промежуточный класс, похоже, тоже играет свою роль ...

...