如何定义这种多对多的教义关联?

cod*_*boy 6 php mysql doctrine-orm

我有两个实体 - 用户和挑战.用户可以参与许多挑战,挑战可以有许多参与者(用户).我开始通过在Users类上创建"多对多"关系来解决此问题:

/**
     * @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;
Run Code Online (Sandbox Code Playgroud)

然而,我意识到我需要针对用户/挑战组合存储距离属性(用户在他们的挑战中走了多远).Doctrine2文档声明:

"为什么多对多关联不太常见?因为经常要将其他属性与关联关联起来,在这种情况下,您会引入一个关联类.因此,直接的多对多关联会消失并被一个关联 - 3个参与课程之间的多对多对多关系."

所以我的问题是用户,挑战和用户挑战之间的这些关联应该是什么?

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

      }

    }
Run Code Online (Sandbox Code Playgroud)

Jon*_*ers 8

用户(一对多) - > UsersChallenges

UsersChallenges(多对一) - >用户

用户挑战(多对一) - >挑战

挑战(一对多) - >用户挑战


Anu*_*rem 1

我相信你想要一个$em->persist($userChallenge);之前$em->flush();

$userChallenge->setDistance( $userChallenge->getDistance() + (int) $distance );
$em->persist($userChallenge);
$em->flush();
Run Code Online (Sandbox Code Playgroud)

但是我不确定它是否能解决您的问题。

您可以在以下位置发帖isEmpty并发挥作用吗containsexistingChallenges