How do I create a form in Symfony 5 for entity with relations to other entities with have other relations in Symfony way?

Viewed 1209

Hi all and thanks in advance for any help! Let's say I have a Symfony 5 App with have entities like: Hero, Profession, ArmorGroup & Armor and WeaponGroup & Weapon. The relation between them is like this:

  • Single unique Hero is a set of one Profession, one Armor and one Weapon
  • Single unique Profession can contain many Heroes, many ArmorGroups and many WeaponGroups
  • Single unique ArmorGroup is a collection of many Armors
  • Single unique WeaponGroup is a collection of many Weapons
  • Single unique Armor is in a collection of one ArmorGroups and is dedicated to one Profession
  • Single unique Weapon is in a collection of one WeaponGroups and is dedicated to one Profession

Here is a diagram: enter image description here

I want to create a HeroType form that limits selection of Armor and Weapon to previously selected Profession and show them as a EntityType single-choice list with names based on data from ArmorGroups for Armor and WeaponGroups for Weapon. All classes have many unique parameters.

Here is my way that is not working:

<?php
class HeroType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', NumberType::class, [
            'attr' => ['placeholder' => 'John Doe'],
            'label' => 'Hero name.',
            'required' => true,
            ])
            ->add('profession', EntityType::class, [
            'choice_label' => 'name',
            'class' => Profession::class,
            'group_by' => 'affiliation',
            'label' => 'Profession',
            'multiple' => false,
            'required' => false,
            ])
            ->add('item_armor', EntityType::class, [
            'choice_label' => 'model',
            'class' => ItemArmor::class,
            'group_by' => 'material',
            'label' => 'Armor',
            'multiple' => false,
            'required' => false,
            ])
            ->add('item_weapon', EntityType::class, [
            'choice_label' => 'model',
            'class' => ItemWeapon::class,
            'group_by' => 'material',
            'label' => 'Weapon',
            'multiple' => false,
            'required' => false,
            ])
            ->add('save', SubmitType::class, ['label' => 'Create Hero!']);
    }

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

It can't get property for 'choice_label' and 'group_by'. I want to make a form for Hero that fetch data from ArmorGroups/WeaponGroups to use as labels, but the values should be Armor/Weapon ID's.

UPDATE: This code render the form correctly and as expected:

<?php
class HeroType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', NumberType::class, [
            'attr' => ['placeholder' => 'John Doe'],
            'label' => 'Hero name.',
            'required' => true,
            ])
            ->add('profession', EntityType::class, [
            'choice_label' => function ($profession) {
                return $profession->getName();},
            'group_by' => function ($profession) {
                return $profession->getAffiliation();},
            'class' => Profession::class,
            'label' => 'Profession',
            'multiple' => false,
            'required' => false,
            ])
            ->add('item_armor', EntityType::class, [
            'choice_label' => function ($item_armor) {
                return $item_armor->getIdItemArmor()->getModel();},
            'group_by' => function ($item_armor) {
                return $item_armor->getIdItemArmor()->getMaterial();},
            'class' => ItemArmor::class,
            'label' => 'Armor',
            'multiple' => false,
            'required' => false,
            ])
            ->add('item_weapon', EntityType::class, [
            'choice_label' => function ($item_weapon) {
                return $item_weapon->getIdItemWeapon()->getModel();},
            'group_by' => function ($item_weapon) {
                return $item_weapon->getIdItemWeapon()->getMaterial();},
            'class' => ItemWeapon::class,
            'label' => 'Weapon',
            'multiple' => false,
            'required' => false,
            ])
            ->add('save', SubmitType::class, ['label' => 'Create Hero!']);
    }

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

But now I get error:

Expected argument of type "App\Entity\Profession or null", "instance of Doctrine\Common\Collections\ArrayCollection" given at property path "profession".

0 Answers
Related