Symfony ManyToMany 关系部分工作

Symfony ManyToMany relationship working partially

我遇到了一个理论上听起来很简单的问题,但在 Symfony 中我无法实现它,所以我希望这里的任何人都可以将我推向正确的方向。

我将首先解释我正在尝试做什么,并让您知道我在多大程度上试图实现这一目标。仅供参考,我使用的是 Symfony 3.0

我想做什么

  1. 我有两个实体 'Post' 和 'Category' 并且它们是链接在一起的 在 ManytoMany 双向关系中一起。
  2. 当我创建一个新的 post 时,我想为其分配一个类别,该类别应该是复选框并与类别实体链接
  3. 保存 post 后,当我对其进行编辑时,类别复选框应显示为 selected(那些分配给 post 的类别)

到目前为止我做了什么

实体已经链接并且关系似乎工作正常,因为当我保存 post 它被保存并且类别的连接 table 和 posts 被更新为post id 和类别 id。如果我 select 多个类别,它们也会在连接 table.

中保存

我卡在什么地方了

当我编辑 post 时,post 数据显示正常,但类别复选框未显示为 selected,这就是我需要您帮助的地方。

我是如何创建表格的。

我不确定这是否是正确的方法,但它似乎有效,所以如果我在某个地方错了并且没有按照 symfony 的方式正确地做,请纠正我。

这是来自 post.orm.yml

的 manyTomany
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
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 实体中创建了一个新的 属性,名称为 Category,在 PostType 中拉动类别来自 Category 实体。

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

    $catagories = $form->get('category')->getData();
    foreach ($catagories as $cat) {
        $post->getCategories()->add($cat);
    }

这样做确实会在加入 table 中保存信息,但是当我编辑它时,复选框不会显示为 selected。

我注意到的另一件奇怪的事情是,如果我从 PostType 中删除 ->add('categories', CollectionType::class,我会收到以下错误,这真的很奇怪,因为这些值不存在于 table 中,所以我不知道为什么它说它们是重复的

posts_categories (post_id, category_id) VALUES (?, ?)' with params [30, 1]: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '30-1' for key 'PRIMARY'

如果有人能告诉我我做错了什么,我将不胜感激。

更新:只需添加一张图片即可显示 post_id 和 category_id 正在保存在加入 table 中

好的,这就是我的发现。

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

  1. 摆脱我在控制器中使用的 foreach 循环
  2. 清理 PostType 如下
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'
    ));
}
}

就是这样,现在我仍然可以在连接 table 中保存 category_idpost_id,并且在编辑时我可以看到默认选择的类别。