Symfony ManyToMany关系部分工作

时间:2016-01-30 12:48:34

标签: php doctrine-orm symfony-forms symfony

我遇到了一个问题,理论上听起来很直接但是在Symfony我无法实现它,所以我希望这里的任何人能够把我推向正确的方向。

我将首先解释一下我想要做什么,并让你知道我试图实现这一目标的程度。仅供参考,我使用的是Symfony 3.0

我想做什么

  1. 我有两个实体' Post'和'类别'他们有联系 一起在ManytoMany关系双向。
  2. 当我创建新帖子时,我想为其分配一个类别,该类别应该是复选框并与类别实体链接
  3. 保存帖子后,当我对其进行编辑时,类别复选框应显示为已选中(分配给帖子的类别)
  4. 到目前为止我做了什么

    实体已经链接,并且关系似乎工作得很好,因为当我保存帖子时,它会被保存,类别和帖子的连接表也会更新,以及帖子ID和类别ID。如果我选择多个类别,它们也会在连接表中保存。

    我被困在

    当我编辑帖子时,帖子数据显示正常,但类别复选框没有显示为已选中,这是我需要你帮助的地方。

    我是如何创建表单的。

    我不确定这是否是正确的方法,但它似乎正在起作用,所以如果我错在某处并且没有按照symfony的方式做对,请纠正我。

    这是来自post.orm.yml

    的许多人
    manyToMany:
        categories:
            targetEntity: MyBundle\Entity\Category
            inversedBy: posts
            joinTable:
                name: posts_categories
                joinColumns:
                    post_id:
                        referencedColumnName: id
                inverseJoinColumns:
                    category_id:
                        referencedColumnName: id
            cascade:  ["persist"]
    

    这是来自category.orm.yml

    的许多人
    manyToMany:
        posts:
            targetEntity: MyBundle\Entity\Post
            mappedBy: categories
            joinTable:
                name: posts_categories
                joinColumns:
                    post_id:
                        referencedColumnName: id
                inverseJoinColumns:
                    category_id:
                        referencedColumnName: id
    

    CategoryType是直截了当的

    class CategoryType extends AbstractType
    {
        /**
         * @param FormBuilderInterface $builder
         * @param array $options
         */
    
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('name');
        }
    
        /**
         * @param OptionsResolver $resolver
         */
        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'MyBundle\Entity\Category'
            ));
        }
    }
    

    这是PostType,这是我怀疑我是否做得对的地方。

    class PostType extends AbstractType
    {
    
        /**
         * @param FormBuilderInterface $builder
         * @param array $options
         */
    
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('title')
                ->add('description')
                ->add('category', EntityType::class, array(
                        'class' => 'MyBundle\Entity\Category',
                        'choice_label' => 'name',
                        'multiple'     => true,
                        'expanded'     => true,
                        'by_reference' => false,
                        ))
                ->add('categories', CollectionType::class, array(
                        'entry_type' => CategoryType::class,
                        'by_reference' => false
                    ));;
        }
    
        /**
         * @param OptionsResolver $resolver
    
         */
        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefaults(array(
    
                'data_class' => 'MyBundle\Entity\Post'
            ));
        }
    }
    

    为了让我显示已创建的类别,我在名为Post的{​​{1}}实体中创建了一个新属性,Category正在从PostType中提取类别实体。

    然后还有Category CollectionType。提交表单时,我使用循环在连接表中添加类别。

    categories

    执行此操作会将信息保存在连接表中,但在编辑时,复选框不会显示为已选中。

    我注意到另一个奇怪的事情,如果我从 $catagories = $form->get('category')->getData(); foreach ($catagories as $cat) { $post->getCategories()->add($cat); } 删除->add('categories', CollectionType::class我得到以下错误,这真的很奇怪,因为这些值不存在于表中,所以我不确定为什么它说他们重复

    PostType

    如果有人能告诉我这里的错误,我将非常感激。

    更新:只需添加图片即可显示post_id和category_id正在保存在连接表中 enter image description here

1 个答案:

答案 0 :(得分:0)

好的,这就是我发现的。

如果关系设置为manyToMany,只要EntityTypemultiple设置为expandedtrue就会呈现为复选框。所以我所要做的就是

  1. 摆脱我在控制器中使用的foreach循环
  2. PostType清理为以下
  3. class PostType extends AbstractType
    {
    
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title')
            ->add('description')
            ->add('categories', EntityType::class, array(
                    'class' => 'MyBundle\Entity\Category',
                    'choice_label' => 'name',
                    'multiple'     => true,
                    'expanded'     => true,
                    'by_reference' => false,
                    ));
    }
    
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
    
            'data_class' => 'MyBundle\Entity\Post'
        ));
    }
    }
    

    多数民众赞成,现在我仍然可以在联接表中保存category_idpost_id,在编辑时我可以看到默认选择的类别。