2011-10-11 5 views
6

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 

     } 

    } 

risposta

1

i essere vive si desidera un $em->persist($userChallenge); prima $em->flush();

$userChallenge->setDistance($userChallenge->getDistance() + (int) $distance); 
$em->persist($userChallenge); 
$em->flush(); 

Tuttavia non sono sicuro se si risolve il problema.

potete inserire isEmpty e contains funzione nel existingChallenges

8

utente (uno-a-molti) -> UsersChallenges

UsersChallenges (molti-a-uno) -> utente

UsersChallenges (molti-a-uno) -> Challenge

Sfide (uno-a-molti) -> UsersChallenges

+0

Grazie. Ti sembrano a posto? https://gist.github.com/1280574, https://gist.github.com/1280576, https://gist.github.com/1280579 – codecowboy

0

Questo codice ha funzionato. Un problema era che stavo testando se una collezione UserChallenge contenesse un oggetto Challenge che ovviamente fallirebbe.

codice di lavoro:

if (!$existingChallenges->isEmpty()) { 

      foreach($existingChallenges as $ec) { 

      $existingChallengeIdArray[] = $ec->getId(); 
      } 
     } 

     if(in_array($challenge_id, $existingChallengeIdArray)) { 


      $userChallenge = $em->getRepository('GymloopCoreBundle:UsersChallenges') 
           ->findOneByChallenge($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($newUserChallenge); 
      $em->flush(); 

     } 
Problemi correlati