Я пытаюсь использовать 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
, чтобы он не былабстрактный, все работает правильно с первым кодом.Таким образом, абстрактный промежуточный класс, похоже, тоже играет свою роль ...