Symfony doctrine ManyToMany单向映射

时间:2017-01-01 20:39:57

标签: symfony doctrine

好吧,再回来,我会尽可能地简化我的问题。

首先,我有2个实体

Post
PostRating

我已经在它们之间创建了单向的ManyToMany关系,因为我只需要将评级添加到每个帖子,如果我尝试将Post映射到PostRating,我会收到循环参考错误。

  

发布实体,它创建第3个表post_has_rating,PostRating实体内没有映射,它工作得像预期,评级集合被添加到每个帖子,但如果我想找到一个评级,并根据需要编辑它,那么它来到比预期更头疼。

/**
 * Post have many PostRating
 * @ORM\ManyToMany(targetEntity="PostRating")
 * @ORM\JoinTable(name="post_has_rating",
 *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="postrating_id", referencedColumnName="id", unique=true)}
 *      )
 */
protected $ratings;
  

PostController thumbAction,简单的单词" ratingAction"

/**
 * Search related videos from youtube
 * @Route("/post/thumb", name="post_thumb")
 * @param Request $request
 * @return string
 */
public function thumbAction (Request $request) {
    $content = json_decode($request->getContent());
    $serializer = $this->get('serializer');
    $em = $this->getDoctrine()->getManager();

    $postRatingRepo = $this->getDoctrine()->getRepository(PostRating::class);
    $postRepo = $this->getDoctrine()->getRepository(Post::class);
    $me = $this->getUser()->getId();

    /** @var PostRating $rating */
    $rating = $postRatingRepo->findOneBy(['userId' => $me]);

    /** @var Post $post */
    $post = $postRepo->find($content->id);

    if ($post->getRatings()->contains($rating)) {
        $post->removeRating($rating);
        $em->remove($rating);
    }

    $rating = new PostRating();
    $rating->setUserId($me);

    switch ($content->action) {
    //NVM about those hardcoded words, they are about to be removed
        case 'up':
                $rating->setRating(1);
            break;
        case 'down':
                $rating->setRating(0);
            break;
    }

    $post->addRating($rating);

        $em->persist($rating);
        $em->persist($post);
        $em->flush();

    return new JsonResponse( $serializer->normalize( ['success' => 'Post thumbs up created'] ) );
}
  

问题:$rating = $postRatingRepo->findOneBy(['userId' => $me]);这一行也需要$post->getRatings()->contains($rating)的postId,现在我得到了我曾经创建的所有raitings,但是如果我添加它会引发错误,Unknown column < / p>

我应该创建自定义存储库,这样我就可以创建像&#34; findRating&#34;用DQL?

OR

我可以让Post和PostRating实体以更简单的方式映射到彼此,我真的不想要多对多的关系,因为我没有看到使用它的意义

1 个答案:

答案 0 :(得分:0)

考虑到你想在这里保持OneToMany单向是我的建议

为您的帖子实体创建自定义存储库

namespace AppBundle\Repository;

use Doctrine\ORM\EntityRepository;

class PostRepository extends EntityRepository
{
    public function findOneRatingByUser($post, $user)
    {
        $query = $this->createQueryBuilder('p')
            ->select('r')
            ->innerJoin('p.ratings', 'r')
            ->where('p.id = :post')
            ->andWhere('r.user = :user')
            ->setParameter('post', $post)
            ->setParameter('user', $user)
            ->getQuery()
        ;

        return $query->getOneOrNullResult();
    }
}

然后在你的控制器中:

public function thumbAction (Request $request)
{
    $content = json_decode($request->getContent());
    $serializer = $this->get('serializer');
    $em = $this->getDoctrine()->getManager();

    $postRepo = $this->getDoctrine()->getRepository(Post::class);
    $me = $this->getUser()->getId();

    /** @var Post $post */
    $post = $postRepo->find($content->id);

    $rating = $postRepo->findOneRatingByUser($post->getId(), $me);

    if (null === $rating) {
        $rating = new PostRating();
        $rating->setUserId($me);   
    }

    switch ($content->action) {
    //NVM about those hardcoded words, they are about to be removed
        case 'up':
                $rating->setRating(1);
            break;
        case 'down':
                $rating->setRating(0);
            break;
    }

    $post->addRating($rating);

        $em->persist($rating);
        $em->persist($post);
        $em->flush();

    return new JsonResponse( $serializer->normalize( ['success' => 'Post thumbs up created'] ) );
}

如果您希望自定义存储库正常工作,请不要忘记在您的实体中声明它

/**
 * @ORM\Entity(repositoryClass="AppBundle\Repository\PostRepository")
 */
class Post