phpsymfonyeasyadmineasyadmin3

Symfony Easy Admin Bundle: Preload nested form data - Fails Entity of type ...must be managed


I'm trying to create a nested form for these three instances, where the inventory has default data, and the nested form InventoryProduct has all the Products in the database by default in the form.

So we add to InventoryCrudCrontroller the createEntityMethod:

public function createEntity(string $entityFqcn)
    {
        $inventory= new Inventory();
        $inventory->setStartDate(new DateTime('now'));
        $inventory->setEndDate(null);

        $productRepository= $this->entityManager->getRepository(MateriaPrima::class);

        $products= $productRepository->findAll();

        foreach ($products as $product) {
            $inventoryProduct= new InventoryProduct();
            $inventoryProduct->setProduct($product);
            $inventoryProduct->setUnits(0);
            $inventoryProduct->setUnitsRejected(0);
            $inventoryProduct->setUnitsQuarantine(0);
            $inventoryProduct->setInventory($inventory);

            $inventory->addInventarioProduct($inventoryProduct);
        }

And on the configureFields method on InventoryCrudCrontroller:

public function configureFields(string $pageName): iterable
    {

        if (Crud::PAGE_EDIT === $pageName || Crud::PAGE_NEW == $pageName) {
            return [
                DateTimeField::new('startDate')
                    ->setColumns(6)
                    ->setValue(new DateTime()),
                DateTimeField::new('endDate')
                    ->setColumns(6),
                CollectionField::new('products', 'Products:')
                    ->onlyOnForms()
                    ->allowAdd()
                    ->allowDelete()
                    ->setEntryIsComplex(false)
                    ->setEntryType(InventoryProductType::class)
                    ->renderExpanded(true)
                    ->setFormTypeOptions(
                        [
                            'by_reference' => false,
                        ]
                    )
                    ->setColumns(12),

And we add the class InventoryProductType for the customs form:

class InventoryProducts extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {

        $builder
            ->add(
                'product',
                EntityType::class,
                ['class' => Product::class, 'label' => '-']
            )
            ->add('units')
            ->add('unitsRejected')
            ->add('unitsQuarantine')
            ;
    }

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


When we try to add another registry, we got:

Entity of type "App\Entity\Inventory" passed to the choice field must be managed. Maybe you forget to persist it in the entity manager?

What am I doing wrong?

Thanks for your help!!


Solution

  • The error tell you that you are using an entity of type App\Entity\Inventory which is not managed by the entity manager.

    If you look into your code, you are creating a new entity in your createEntity method, but never persisted it.

    You could either persist it in your method like:

    public function createEntity(string $entityFqcn)
        {
            $inventory= new Inventory();
            $inventory->setStartDate(new DateTime('now'));
            $inventory->setEndDate(null);
            $this->entityManager->persist($inventory);
    
            $productRepository= $this->entityManager->getRepository(MateriaPrima::class);
    
            $products= $productRepository->findAll();
            
            foreach ($products as $product) {
                $inventoryProduct= new InventoryProduct();
                $inventoryProduct->setProduct($product);
                $inventoryProduct->setUnits(0);
                $inventoryProduct->setUnitsRejected(0);
                $inventoryProduct->setUnitsQuarantine(0);
                $inventoryProduct->setInventory($inventory);
                $this->entityManager->persist($inventoryProduct);
    
                $inventory->addInventarioProduct($inventoryProduct);
            }
        }
    

    Or add cascading persist on your entity.