2011-10-11 24 views
6

Tôi có hai Thực thể - Người dùng & Thách thức. Người dùng có thể tham gia vào nhiều thử thách và thách thức có thể có nhiều người tham gia (người dùng). Tôi bắt đầu tiếp cận vấn đề này bằng cách tạo ra một mối quan hệ Nhiều-To-Nhiều người trên lớp Users tôi:Cách liên kết doctrine2 Nhiều-Nhiều này được xác định như thế nào?

/** 
    * @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; 

Tuy nhiên, sau đó tôi nhận ra rằng tôi cần phải lưu trữ một thuộc tính khoảng cách chống lại một sự kết hợp dùng/thách thức (cách xa người sử dụng đã đi trong thử thách của họ). Tài liệu Doctrine2 có trạng thái:

"Tại sao nhiều liên kết ít phổ biến hơn? Bởi vì thường xuyên bạn muốn liên kết các thuộc tính bổ sung với một liên kết, trong trường hợp này bạn giới thiệu một lớp kết hợp. nhiều hiệp hội biến mất và được thay thế bằng các liên kết một-nhiều/nhiều-một giữa ba lớp tham gia. "

Vì vậy, câu hỏi của tôi là những gì các hiệp hội này nên là giữa Người dùng, Thách thức và Người dùngChallenges?

CẬP NHẬT

Xem bình luận cho câu trả lời đầu tiên cho các liên kết đến các mã Entity. Tôi có một phương pháp điều khiển bên dưới mà luôn luôn tạo ra một kỷ lục UsersChallenges mới chứ không phải cập nhật hiện có (đó là những gì tôi muốn)

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 

     } 

    } 

Trả lời

1

i được sống bạn muốn có một $em->persist($userChallenge); trước $em->flush();

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

Tuy nhiên tôi không chắc chắn nếu nó giải quyết vấn đề của bạn.

Bạn có thể gửi isEmptycontains chức năng trong existingChallenges

8

tài khoản (one-to-many) -> UsersChallenges

UsersChallenges (nhiều-to-one) -> người dùng

UsersChallenges (nhiều-to-one) -> Challenge

Challenge (one-to-many) -> UsersChallenges

+0

Cảm ơn. Làm những điều này ok cho bạn? https://gist.github.com/1280574, https://gist.github.com/1280576, https://gist.github.com/1280579 – codecowboy

0

Mã này làm việc. Một vấn đề là tôi đã thử nghiệm xem một bộ sưu tập UserChallenge có chứa một đối tượng Challenge mà rõ ràng là sẽ thất bại.

đang làm việc:

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

     } 
Các vấn đề liên quan