Ho due entità - Utenti & Sfide. Un utente può partecipare a molte sfide e una sfida può avere molti partecipanti (utenti). Ho cominciato affrontare questo problema con la creazione di una relazione molti-a-molti sulla mia classe Utenti:Come deve essere definita questa associazione di molti a molti doctrine2?
/**
* @ORM\ManytoMany(targetEntity="Challenge")
* @ORM\JoinTable(name="users_challenges",joinColumns={@ORM\JoinColumn(name="user_id",referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="challenge_id",referencedColumnName="id")})
*
*/
protected $challenges;
Tuttavia, ho poi capito che ho bisogno di memorizzare un attributo di distanza contro un combinazione utente/sfida (fino a che punto l'utente ha viaggiato nella loro sfida). Doctrine2 docs state:
"Perché le associazioni molti-a-molti sono meno comuni? Perché spesso si associano attributi aggiuntivi a un'associazione, nel qual caso si introduce una classe di associazione. molte associazioni scompaiono e vengono sostituite da associazioni uno a molti/molti a uno tra le 3 classi partecipanti. "
Quindi la mia domanda è: quali dovrebbero essere queste associazioni tra User, Challenge e UsersChallenges?
UPDATE
See commento alla prima risposta per i collegamenti al codice entità. Ho un metodo di controllo di sotto della quale crea sempre un nuovo record UsersChallenges invece di aggiornare uno esistente (che è quello che voglio)
public function updateUserDistanceAction()
{
$request = $this->getRequest();
$distance = $request->get('distance');
$challenge_id = $request->get('challenge_id');
if($request->isXmlHttpRequest()) {
$em = $this->getDoctrine()->getEntityManager();
$user = $this->get('security.context')->getToken()->getUser();
$existingChallenges = $user->getChallenges();
$challengeToUpdate = $em->getRepository('GymloopCoreBundle:Challenge')
->find((int) $challenge_id);
if(!$challengeToUpdate) {
throw $this->createNotFoundException('No challenge found');
}
//does the challengeToUpdate exist in existingChallenges? If yes, update UsersChallenges with the distance
//if not, create a new USersChallenges object, set distance and flush
if (!$existingChallenges->isEmpty() && $existingChallenges->contains($challengeToUpdate)) {
$userChallenge = $em->getRepository('GymloopCoreBundle:UsersChallenges')
->findOneByChallengeId($challengeToUpdate->getId());
$userChallenge->setDistance($userChallenge->getDistance() + (int) $distance);
$em->flush();
} else {
$newUserChallenge = new UsersChallenges();
$newUserChallenge->setDistance($distance);
$newUserChallenge->setChallenge($challengeToUpdate);
$newUserChallenge->setUser($user);
$user->addUsersChallenges($newUserChallenge);
$em->persist($user);
$em->persist($newUserChallenge);
$em->flush();
}
//if success
return new Response('success');
//else
}
}
Grazie. Ti sembrano a posto? https://gist.github.com/1280574, https://gist.github.com/1280576, https://gist.github.com/1280579 – codecowboy