2011-10-11 87 views
6

我有兩個實體 - 用戶&的挑戰。用戶可以參與許多挑戰,並且挑戰可以讓許多參與者(用戶)參與。我開始通過創建我的用戶類別的許多一對多的關係,處理這個問題:這個多對多的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; 

然而,我才明白,我需要存儲對用戶/挑戰組合的距離屬性(多遠用戶已經走過了挑戰)。 Doctrine2文檔狀態:

「爲什麼多對多關聯不太常見?因爲您經常希望將其他屬性與關聯關聯起來,在這種情況下,您需要引入關聯類,因此,直接」多對多「許多關聯消失,並被3個參與類之間的一對多/多對一關聯所取代。「

所以我的問題是這些關聯應該在User,Challenge和UsersChallenges之間做什麼?

UPDATE

看到,鏈接到實體代碼第一個答案評論。下面我有它總是創建一個新的UsersChallenges記錄,而不是更新現有的一個(這是我想要什麼)

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 

     } 

    } 

回答

1

我是過着自己想要一個$em->persist($userChallenge);$em->flush();

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

但是我不知道它是否解決您的問題。

您可以發佈isEmptyexistingChallenges

8

用戶(一到多)的控制方法 - > UsersChallenges

UsersChallenges(許多對一) - >用戶

UsersChallenges(多到一個) - >挑戰

挑戰(一到多) - > UsersChallenges

+0

感謝。這些看起來對你好嗎? https://gist.github.com/1280574,https://gist.github.com/1280576,https://gist.github.com/1280579 – codecowboy

0

此代碼工作contains功能。一個問題是我正在測試一個UserChallenge集合是否包含一個顯然失敗的Challenge對象。

工作代碼:

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(); 

     }