如何在Symfony2中使用多对多关系

时间:2017-05-22 07:07:54

标签: php mysql forms symfony

我正在开发一个基于Symfony 2的网络应用,并努力创建实体之间的多对多关系:

应将每个Task实体分配给任意数量的Categories。当然,任何数量的Category实体都可以使用每个Task。虽然Task需要知道其Categories,但Category类与Tasks没有任何关系。

关注this tutorial我创建了:

class Task {    
    /**
    * @ORM\Column(name="categories")
    * @ORM\ManyToMany(targetEntity="MyBundle\Entity\Category")
    */
    protected $categories;

    public function __construct() {
        $this->productVariations = new \Doctrine\Common\Collections\ArrayCollection();
        ...
    }
}

这导致以下SQL表:

CREATE TABLE task ... categories VARCHAR(255) NOT NULL, ...

使用具有以下类型的表单创建新的Task

class TaskType extends AbstractType {
    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder
            ->add('categories', EntityType::class, array(
                'class' => 'MyBundle:Category',
                'choice_label' => 'name',
                'multiple' => true,
                'expanded' => true,
            ))
            ...
    }
}

提交表单并将新的Task实例结果保存在categories列中包含以下内容的SQL行中:

Doctrine\Common\Collections\ArrayCollection@000000007448a17a0000000048941f2f

这是什么意思?将引用的Category实体存储为数组不是正常形式,但当然有效(实际上我更倾向于这个解决方案而不是添加关系表,因为在实践中每个任务的类别数量非常少,因此第三个表格的开销会更大。

但是我假设数组以某种形式存储引用的对象/行的ID。如何在VARCHAR(255)列中存储任意数量的引用?

提交和持久创建数据库条目时,Category引用未正确存储。当我尝试重新读取此条目时,categories属性为空。

2 个答案:

答案 0 :(得分:1)

您有冗余列定义。尝试简单地删除以下行:

  export default Vue.component('st-filter', {
    data () {
      return {
        selectModel: "",
        dropdown : [],
      }
    },
    methods: {
      populateDates: function () {
        let date7daysAgo, date1monthAgo...
        this.dropdown = [`Last week (${date7daysAgo} - ${dateToday})`, `Last month (${date7daysAgo} - ${date1monthAgo})` ];
        this.selectModel = this.dropdown[0];

      }
    },
    created() {
      this.populateDates();
    }
  });

然后您需要更新数据库架构。

此行在任务表中创建一个* @ORM\Column(name="categories") 字段,该字段不应存在。许多关系都是通过单独的表来实现的。

如果您想将ID存储在单个字段而不是单独的表中,那么您将自己处理它。那是因为它不再能够成为一种关系。您无法创建外键或执行任何连接查询。此外,过滤记录将更难实现。

答案 1 :(得分:0)

我认为你在这里遗漏了一些东西。

就像你说的那样,Task可以与许多Category相关联,Category类不需要与Task类的关系映射。< / p>

Task课程中所需要的只是引用您的类别的属性。

我认为你要找的是this