Как определить эту связь доктрины «многие ко многим»? - PullRequest
6 голосов
/ 11 октября 2011

У меня есть две сущности - пользователи и вызовы.Пользователь может участвовать во многих задачах, и задача может иметь много участников (пользователей).Я начал подходить к этой проблеме, создав отношение «многие ко многим» в своем классе «Пользователи»:

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

ОБНОВЛЕНИЕ

См. Комментарий к первому ответу для ссылок на код сущности.У меня есть метод контроллера ниже, который всегда создает новую запись 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

      }

    }

Ответы [ 3 ]

8 голосов
/ 11 октября 2011

Пользователь (один ко многим) -> UsersChallenges

UsersChallenges (многие-к-одному) -> Пользователь

UsersChallenges (многие-к-одному) -> Challenge

Вызов (один ко многим) -> UsersChallenges

1 голос
/ 21 октября 2011

я верю, что вы хотите $em->persist($userChallenge); до $em->flush();

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

Однако я не уверен, решит ли это вашу проблему.

Можете ли вы опубликовать isEmpty и contains функцию в existingChallenges

0 голосов
/ 23 октября 2011

Этот код работал.Одна проблема заключалась в том, что я проверял, содержит ли коллекция 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();

        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...