Andrei Herford Andrei Herford -4 years ago 106
PHP Question

How to use a many to many relationship in Symfony2

I am working on a

Symfony 2
based web app and struggling to create a many to many relationship between to entities:

Each
Task
entity should be assigned to any number of
Categories
. Of course each
Category
can be used by any number of
Task
entities. While a
Task
needs to know its
Categories
the
Category
class has no relationship back to the
Tasks
.

Following this tutorial I created:

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

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


Which results in the following SQL table:

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


A new
Task
is created use a form with the following type:

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,
))
...
}
}


Submitting the form and persiting the new
Task
instance result in a SQL row with the following content in the
categories
column:

Doctrine\Common\Collections\ArrayCollection@000000007448a17a0000000048941f2f


What does this mean? Storing the referenced
Category
entities as array is not normal form but of course valid (in fact I would prefer this solution over adding a relationship table since in practice the number of categories per task will be quite small, thus a third table would be more overhead).

However I would assume that the array stores the IDs of the referenced objects/rows in some form. How would it be possible to store any number of references in a
VARCHAR(255)
column?

While submitting and persisting creates a DB entry, the
Category
references are not stored correctly. When I try to re-read this entry, the
categories
property is empty.

Answer Source

You have redundant column definition. Try to simply remove following line:

* @ORM\Column(name="categories")

Then you need to update you database schema.

This line creates a varchar field in task table which shouldn't be there. Many to many relations are implemented via separate table.

If you want to store ids in a single field instead of separate table, then you will handle it on your own. That's because it won't be able to be a relation anymore. You loose possibility to create foreign key or doing any join queries. Also filtering records will be harder to achieve.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download