Как реализовать контрольный список через «отношения ManyToMany с дополнительной информацией»? - PullRequest
0 голосов
/ 18 марта 2019

В проекте symfony4 у меня есть сущность Order, которую я хочу связать с другой сущностью ChecklistItem через отношения ManyToMany, но с дополнительной информацией. Это достаточно просто сделать, создав промежуточную сущность OrderChecklist, как в этот подход .

В моей форме ввода / редактирования заказа я хочу, чтобы для каждого заказа отображался полный «контрольный список», чтобы я мог отслеживать, когда различные части выполнения заказа завершены. Я не могу понять, как это реализовать.

Один из вариантов - создать полный связанный контрольный список, содержащий все элементы контрольного списка для каждого заказа вместе с параметром «выполнено», но это кажется расточительным. Вместо этого я хотел бы показать флажок всех элементов контрольного списка и позволить пользователю отмечать элементы по мере их завершения и сохранять их в сущности OrderChecklist. Вот чего я не могу понять.

Вот что у меня есть.

Элемент контрольного списка:

/**
 * @ORM\Entity()
 */
class ChecklistItem
{
    /**
     * @ORM\OneToMany(targetEntity="OrderChecklist", mappedBy="checklistItem")
     */
    private $orderChecklistItems;

    // ... other parameters ...
}

Заказ:

/**
 * @ORM\Entity()
 */
class Order
{
    /**
     * @ORM\OneToMany(targetEntity="OrderChecklist", mappedBy="order")
     */
    private $orderChecklistItems;

    // ... other parameters ...
}

Таблица линкеров:

/**
 * @ORM\Entity()
 */
class OrderChecklist
{
    /**
     * @ORM\ManyToOne(targetEntity="Order", inversedBy="orderChecklistItems")
     */
    private $order;

    /**
     * @ORM\ManyToOne(targetEntity="ChecklistItem", inversedBy="orderChecklistItems")
     */
    private $checklistItem;

    /**
     * @ORM\Column(type="datetime")
     */
    private $completionDate;

    // ... other parameters ...
}

При рендеринге формы заказа с CollectionType у меня есть это:

class OrderFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('orderChecklistItems', CollectionType::class, [
                'entry_type' => ChecklistItemEmbeddedForm::class,
            ])
            // ... add other parameters ...
            ;
    }
}

с моей вложенной формой:

class ChecklistItemEmbeddedForm extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('checklistItem', EntityType::class, [
                'class' => ChecklistItem::class,
                'multiple' => true,
                'expanded' => true,
            ]);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(['data_class' => OrderChecklist::class]);
    }
}

Форма может быть обработана с моего контроллера:

class OrderController extends AbstractController
{
    public function edit(Request $request, Order $order)
    {
        $form_order = $this->createForm(OrderFormType::class, $order);

        $form_order->handleRequest($request);
        if ($form_order->isSubmitted() && $form_order->isValid()) {
            $order = $form_order->getData();

            $em = $this->getDoctrine()->getManager();
            $em->persist($order);
            $em->flush();

            return $this->redirectToRoute('order_edit', ['id'=>$order->getId()]);
        }

        return $this->render('order/main.html.twig', [
            'form_order' => $form_order->createView(),
        ]);
    }
}

а затем из ветки:

{{ form_start(form_order) }}
    {{ form_row(form_order.orderChecklistItems) }}
{{ form_end(form_order) }}

Я знаю, что могу использовать прототипы, чтобы предлагать по одному ChecklistItem за раз по документации Symfony, но это не то поведение, которого я придерживаюсь.

Казалось бы, мне не хватает чего-то простого и очевидного в моей форме. Что это?

...