Formularz Symfony z dziedziczeniem tabeli klas Doctrine (CTI)

Nov 23 2020

W poprzednim pytaniu, które zadałem, jak obsługiwać duże formularze, wynikiem było dziedziczenie pojedynczej tabeli (STI) lub CTI, mapowanie dziedziczenia . Wybrałem CTI.

Teraz zajmuję się tworzeniem formularza za pomocą CTI. Szybki przegląd, jakiego rodzaju lub relacji istnieją.

Każdy inspectionmoże mieć jeden lub więcej surfaces. Każda powierzchnia składa się z wielu jednostek podrzędnych, jak: surface_leakage, surface_tensionlub surface_slope. Jak widać, surfacema CTI z podmiotami podrzędnymi. Niektóre pola pokrywają się (umieść je w rodzicu), inne nie (umieść je w potomku). Ale w końcu potrzebuję jednego formularza ze wszystkimi polami pogrupowanymi według powierzchni, a następnie według dzieci (może zwijanie Bootrap).

Nawiązanie relacji nie było takie trudne, ale użycie jej w formie jest trudne i nie jestem pewien, jak sobie z tym poradzę. Zobacz poniższy kod z dwoma zatwierdzeniami w kodzie

<?php
class Inspection
{
    /**
     * @OneToMany(targetEntity="App\Entity\Surface", mappedBy="inspection")
     */
    protected $surfaces; } /** * @Entity * @InheritanceType("JOINED") * @DiscriminatorColumn(name="discr", type="string") * @DiscriminatorMap({"surface" = "Surface", "surface_leagage" = "SurfaceLeakage", ...}) */ class Surface { protected $inpection;
    protected $description; } class SurfaceLeakage extends Surface { protected $leakageLevel;
}

// .. other child classes (SurfaceTension, SurfaceSlope, ...)

class InspectionType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // ...

        $builder->add('surfaces', CollectionType::class, [ 'entry_type' => SurfaceType::class, ]); } } // Approach 1, where each child is added to the SurfaceType // with this approach data should be mapped false // This approach ensures that I only have to call SurfaceType once and all fields are loaded, but // could not make this work with data from DB through CIT. // Also this method does not allow me to add field description (from parent) to all childTypes class SurfaceType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('leakage', SurfaceLeakageType::class, array('mapped' => false));
        $builder->add('tension', SurfaceTensionType::class, array('mapped' => false)); // ... } public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([ 'data_class' => Surface::class, ]); } } class SurfaceLeakageType extends AbstractType { } // Approach 2, where each childFormType could extend SurfaceType, like below but how to call/create the // form and handling the data. // With this approuch i could parent fields to the child class SurfaceLeakageType extends SurfaceType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('description', TextareaType::class); // field from parent or ...
        parent::buildForm($builder, $options);


        $builder->add('leakageLevel', IntegerType::class); // own field
        //  ...
    }
}

Następnie jest forma inherit_data

// Approach 3, inherit data, now each child should add this as a field like below,
// but how the only thing I'm doing on InspectionType build Surfaces as collection so
// i think inherit data also doesn't work
class SurfaceType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->add('description', TextareaType::class);
    }

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

class SurfaceLeakageType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // inherit fields
        $builder->add('leakage', SurfaceType::class, [ 'data_class' => SurfaceLeakage::class, ]); $builder->add('leakageLevel', IntegerType::class); // own field
    }
}

Mam nadzieję, że ktoś może mi pomóc

Odpowiedzi

1 Stev Nov 24 2020 at 06:07

Myślę, że szukasz form polimorficznych. Sprawdź ten pakiethttps://github.com/infinite-networks/InfiniteFormBundle