2

I'm on a project where I have a many to many relationship between team and agent. Because my teams can have multiple agents and my agents can have multiple teams.

I'm in a situation where I'm doing a patch so I can add multiple agents to a team (which is working) but I cannot do a working patch to add multiple teams to an agent.

Is it because of mapped by and inversed by?

UPDATE

In my TEAM entity here is the relation

/**
 * @ORM\ManyToMany(targetEntity="MyBundle\Entity\Agent", inversedBy="teams")
 */
private $agents;

Here is the relation in my AGENT entity

/**
 * @ORM\ManyToMany(targetEntity="MyBundle\Entity\Team", mappedBy="agents")
 */
private $teams;

In my team controller, when I want to give my team some new agents I'm using this piece of code and it works. I can see all the agents associated to the team in the database.

$team->setAgents($theAgents);

But when I want to do the opposite in my agent controller (assigning some teams to a new agent) the agent is created in the database but it's not assigned to any team in the association table. Even if I'm using this: $agent->setTeams($theTeams);

Hence, is it maybe because it's not possible with Doctrine? Or perhaps I'm missing something.

Frabot
  • 41
  • 7

2 Answers2

3

This is the expected behavior.

For your ManyToMany relation you have the owning side:

/**
 * @ORM\ManyToMany(targetEntity="MyBundle\Entity\Agent", inversedBy="teams")
*/
private $agents;

and the inverse side:

/**
 * @ORM\ManyToMany(targetEntity="MyBundle\Entity\Team", mappedBy="agents")
*/
private $teams;

which are defined by the settings inversedBy and mappedBy respectively.

For a ManyToMany relation, you can chose which entity is the owning and which the inverse side, either of them can be defined.

Doctrine only checks the owning side for association changes. Check Working with associations, which means on your case, only $agents of Teams is checked for any changes to be persisted in the database.

On Agents, any changes in teams are ignored.

Changes made only to the inverse side of an association are ignored. Make sure to update both sides of a bidirectional association (or at least the owning side, from Doctrine's point of view)

It is your responsibility to include these changes on the owning side also.

So in setTeams, do something like:

public function setTeams($teams) {
    $this->teams = $teams;
    foreach($teams as $team) {
        $team->addAgent($this);
    }
}

Note that in addAgent you have to check if the agent already exists in the collection.

Jannes Botis
  • 11,154
  • 3
  • 21
  • 39
  • 1
    Thanks a lot for your comment! I used a solution similar in the end! In my controller I added /** * @param mixed $team */ public function addTeam(Team $team) { $this->teams[] = $team; $team->addAgent($this); } and then did the foreach in my controller! I think I didn't understand this side of the Many to Many relation but now I see! – Frabot May 03 '18 at 19:42
0

In the end the solution I found is similar to Jannes'.

In my Agent entity I added this function:

 /**
 * @param mixed $team
 */
public function addTeam(Team $team)
{
    $this->teams[] = $team;
    $team->addAgent($this);
}

and in my Agent controller:

$teams = $request->get('teams');
foreach ($teams as $team){
   $myTeam = $em->getRepository('MyBundle:Team')
            ->find($team["id"]);
   $agent->addTeam($myTeam);
}

By doing so, I was I able to have a working post on both sides! Thank you all again for your help!

Frabot
  • 41
  • 7