Symfony Form mit Doctrine Class Table Inheritance (CTI)

Nov 23 2020

In einer früheren Frage, die ich zum Umgang mit großen Formularen gestellt habe, war das Ergebnis Single Table Inheritance (STI) oder CTI, Inheritance Mapping . Ich habe mich für CTI entschieden.

Jetzt beschäftige ich mich mit dem Erstellen des Formulars mit CTI. Ein kurzer Überblick darüber, welche Art oder Beziehung es gibt.

Jeder inspectionkönnte einen oder mehrere haben surfaces. Jede Oberfläche besteht aus vielen Untereinheiten, wie: surface_leakage, surface_tensionoder surface_slope. Wie Sie sehen konnten, surfacehat die CTI mit Unterentitäten. Einige Felder überlappen sich (setzen sie in Eltern), andere nicht (setzen sie in Kinder). Aber am Ende brauche ich ein Formular mit allen Feldern, die nach Oberflächen und dann nach Kind gruppiert sind (möglicherweise Bootrap-Zusammenbruch).

Das Einrichten der Beziehung war nicht so schwierig, aber es ist schwierig, sie in eine Form zu bringen, und ich bin mir nicht sicher, wie ich damit umgehen soll. Siehe folgenden Code mit in Code zwei Ansätzen

<?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
        //  ...
    }
}

Dann gibt es das Formular 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
    }
}

Hoffe jemand könnte mir helfen

Antworten

1 Stev Nov 24 2020 at 06:07

Ich denke, Sie suchen nach polymorphen Formen. Überprüfen Sie dieses Bundlehttps://github.com/infinite-networks/InfiniteFormBundle