2011-10-11 92 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(); 

     }