Doctrine Class Table Inheritance(CTI)を使用したSymfonyフォーム

Nov 23 2020

で前の質問私は大規模なフォームをどのように処理するかを尋ね、結果は単一テーブル継承(STI)やCTI、だっ継承マッピング。私はCTIに選びました。

今、私はCTIでフォームを作成する方法を扱っています。どのような種類または関係があるかについての簡単な概要。

それぞれにinspection1つ以上のがありsurfacesます。各表面は次のように、多くのサブエンティティで構成されていますsurface_leakagesurface_tensionまたはsurface_slope。ご覧のとおりsurface、サブエンティティを持つCTIがあります。一部のフィールドは重なり合う(親に置く)ものもあれば、重なり合わない(子に置く)ものもあります。しかし、最終的には、すべてのフィールドがサーフェスごとにグループ化され、次に子ごとにグループ化された1つのフォームが必要です(おそらくBootrapが崩壊します)。

リレーションの設定はそれほど難しくありませんでしたが、フォームに使用するのは難しく、これをどのように処理できるかわかりません。以下のコードを参照してください。コードには2つのアプローチがあります。

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

次に、フォーム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
    }
}

誰かが私を助けてくれることを願っています

回答

1 Stev Nov 24 2020 at 06:07

多形を探していると思います。このバンドルを確認してくださいhttps://github.com/infinite-networks/InfiniteFormBundle