ECCUBE4 Symfony EntityTypeフォームで多対多 Many To Many メモ


個人的なメモです

EntityType の多対多 ManyToMany のとき(汗

select、radio、check、 listに対応するChoiceTypeフォームがありますが
ChoiceTypeフォームを外部テーブル参照したものがEntitytypeです
設定が特にいやらしいです

Twigファイルで多対多の従テーブルをチェックボックスで表示した例
※ここでは、多対多の主をデッキテーブル、従をデッキタグテーブルとします

    <div>
        <div>
            <label>デッキタグ</label>                  //ラベル(任意)
        </div>

 //エンティティループ表示=デッキタグテーブルに存在するレコード(タグ名)を表示
        <div>
        {% for deckTag in form.deckTags %}  //変数deckTagsはRepositoryでManyToMany定義
            <div>                                     
               {{ form_widget(deckTag) }}  //変数deckTagsから取り出したdecktagを表示
            </div>
        {% endfor %}
        {{ form_errors(form.deckTags) }}
        </div>
    </div> 
フォームタイプの記述 Customize/Form/Type/Admin/FormType.php
<?php

namespace Customize\Form\Type\Admin;

//useは割愛

class FormType extends AbstractType
{
    public function __construct()
    {
    }

    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
        ->add('deckTags', EntityType::class, [   //多対多 主デッキEntityクラスの変数deckTags参照
            'class' => DeckTag::class,           //多対多 従デッキタグEntityクラス参照
            'choice_label' => 'name',            //nameカラムの値を表示
            'expanded' => true,                  //下の表を参照
            'multiple' => true,                  //ラジオボタン
            ]) 
         ;
    }

こんな感じになります。
タグを複数選択してPOSTしたり、複数選択のAND検索ができますね。

for文を使わないパターン
    <div>
        <label>デッキタグ</label>
        {{ form_widget(form.deckTags) }}
        {{ form_errors(form.deckTags) }}
    </div> 

こうなりました 横並びしたいのに、いうこときいてくれません(汗

公式:ChoiceType のオプション解説
https://symfony.com/doc/current/reference/forms/types/choice.html

EntityTypeの各オプションを試してみた

EntityTypeのラジオボタン
'expanded' => true,
'multiple' => false   
とすると

Entity of type "Doctrine\Common\Collections\ArrayCollection" passed to the choice field must be managed. Maybe you forget to persist it in the entity manager?
HTTP500内部サーバーエラー
選択フィールドに渡されるタイプDoctrine \ Common \ Collections \ ArrayCollectionのエンティティを管理する必要があります エンティティマネージャでそれを永続化するのを忘れているかもしれませんか

はいお手上げです
EntityTypeのセレクトボックス
'expanded' => false,
'multiple' => false  
または
'expanded' => false,
'multiple' => true   

はい、何もでません

EntityTypeのセレクトボックス/ループ呼び出しをしないやり方
Twigを...
    <div>
        <label>デッキタグ</label>
        <span>{{ 'admin.common.required'|trans }}</span>
        {{ form_widget(form.deckTags) }}
        {{ form_errors(form.deckTags) }}
    </div> 
()

フォームオプションを...
'expanded' => false,
'multiple' => false  

セレクトボックスがでてくれます

セレクトボックスマルチはできるのか
Twigを...
    <div>
        <label>デッキタグ</label>
        <span>{{ 'admin.common.required'|trans }}</span>
        {{ form_widget(form.deckTags) }}
        {{ form_errors(form.deckTags) }}
    </div> 

フォームオプションを...
'expanded' => false,
'multiple' => ture  

リストボックスがでました、複数選択はできません(残念

以下はエンティティファイルです

テーブル紐づけ:主側 Customize/Entity/Deck.php
    /**
     * @var \Doctrine\Common\Collections\Collection
     * 
     * @ORM\ManyToMany(targetEntity="Customize\Entity\DeckTag", mappedBy="decks")
     */
    private $deckTags;   この変数をtwigで使う
テーブル紐づけ:従側 Customize/Entity/DeckTag.php
    /**
     * @var \Doctrine\Common\Collections\Collection
     * 
     * @ORM\ManyToMany(targetEntity="Deck", inversedBy="deckTags")
     * @ORM\JoinTable(
     *  name="dtb_deck_deck_tag",
     *  joinColumns={
     *      @ORM\JoinColumn(name="deck_tag_id", referencedColumnName="id")
     *  },
     *  inverseJoinColumns={
     *      @ORM\JoinColumn(name="deck_id", referencedColumnName="id")
     *  }
     * )
     */
    private $decks;

おわりに

ECCUBE4、SymfonyフレームワークについてはRubyOnRailsと違って
参考書や日本語ソースや新しい情報が少ないです
Symfony公式ドキュのが情報網羅性がう~~んな感じ。
現在ネットに公表されている情報が貴重でとても参考になっております。
公表してくださっている先輩エンジニアの方々にお礼申し上げます。