ManyToMany与symfony2 orm doctrine中的额外字段的关系

时间:2013-03-04 14:54:05

标签: symfony orm many-to-many entity-relationship

你好我有同样的问题:Many-to-many self relation with extra fields?但是我找不到答案:/我首先尝试了ManyToOne,而在另一个网站OneToMany ...但是我不能使用像

这样的东西
    public function hasFriend(User $user)
{
    return $this->myFriends->contains($user);
}  

因为有一些问题:

This function is called, taking a User type $user variable and you then use the contains()      function on $this->myFriends.

$ this-> myFriends是一个请求的ArrayCollection(与用户类型不同),以及关于contains()的doctrine文档:

The comparison of two elements is strict, that means not only the value but also the type must match.

那么用额外字段解决这个ManyToMany关系的最佳方法是什么?或者,如果我回去设置onetomany和manytoone关系,我怎么能修改hasFriend方法?例如,检查ID是否在ID的数组集合中。

编辑:我有这张桌子......我需要的是: 1.选择我的朋友......和我的粉丝......检查我是否是他的朋友。 (因为他可以和我成为朋友,我不必和他在一起......就像在推特上一样)。我可以制作很多但我需要额外的字段,例如:“查看”“他订阅我的时间”,你可以在我的桌子上看到。

然后像这样进行查询,然后能够在树枝上检查是否(app.user.hasFriend(追随者)或类似的东西)

           $qb = $this->createQueryBuilder('r')
                  ->select('u')
                  ->innerJoin('UserBundle:User', 'u')
                  ->Where('r.friend_id=:id')
                  ->setParameter('id', $id)
                  ->orderBy('r.time', 'DESC')
                  ->setMaxResults(50);

    return $qb->getQuery()
              ->getResult();

enter image description here

2 个答案:

答案 0 :(得分:5)

我试图与额外的字段建立多对多的关系,并且无法使其工作......我在论坛中阅读的内容(无法记住在哪里)是:

  

如果您向关系添加数据,那么它就不再是关系了。它是一个新实体。

这是正确的做法。使用新字段创建新实体,如果需要,可以创建自定义存储库以添加所需的方法。

A< ---许多人与领域--->乙

会变成

A - 一对多 - > C(带新字段)< - 一对多 - B

当然,C与A和B都有ManyToOne关系。

我到处搜索如何做到这一点,但最后,这是正确的做法,如果你添加数据,它就不再是一种关系。

您还可以复制通常包含的内容,或尝试在自定义存储库中覆盖它,以执行您需要执行的操作。

我希望这会有所帮助。

答案 1 :(得分:3)

我正在添加另一个答案,因为它与我的原始答案无关。使用您发布的新信息,我正在调用您发布的“关注者”表格/实体。原始实体“用户”。

如果您创建以下关联会发生什么:


namespace Acme\UserBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Acme\UserBundle\Entity\User
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class User
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\OneToMany(targetEntity="Acme\FollowerBundle\Entity\Follower", mappedBy="followeduser")
     */
    protected $followers;

    /**
     * @ORM\OneToMany(targetEntity="Acme\FollowerBundle\Entity\Follower", mappedBy="followeeuser")
     */
    protected $followees;

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }
    public function __construct()
    {
        $this->followers = new \Doctrine\Common\Collections\ArrayCollection();
    $this->followees = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Add followers
     *
     * @param Acme\FollowerBundle\Entity\Follower $follower
     */
    public function addFollower(\Acme\FollowerBundle\Entity\Follower $follower)
    {
        $this->followers[] = $follower;
    }

    /**
     * Add followees
     *
     * @param Acme\FollowerBundle\Entity\Follower $followee
     */
    public function addFollowee(\Acme\FollowerBundle\Entity\Follower $followee)
    {
        $this->followees[] = $followee;
    }    

    /**
     * Get followers
     *
     * @return Doctrine\Common\Collections\Collection 
     */
    public function getFollowers()
    {
        return $this->followers;
    }

    /**
     * Get followees
     *
     * @return Doctrine\Common\Collections\Collection 
     */
    public function getFollowees()
    {
        return $this->followees;
    }
}


namespace Acme\FollowerBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Acme\FollowerBundle\Entity\Follower
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class Follower
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="Acme\UserBundle\Entity\User", inversedBy="followers")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    protected $followeduser;

    /**
     * @ORM\ManyToOne(targetEntity="Acme\UserBundle\Entity\User", inversedBy="followees")
     * @ORM\JoinColumn(name="followee_id", referencedColumnName="id")
     */
    protected $followeeuser;

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set followeduser
     *
     * @param Acme\UserBundle\Entity\User $followeduser
     */
    public function setFolloweduser(\Acme\UserBundle\Entity\User $followeduser)
    {
        $this->followeduser = $followeduser;
    }

    /**
     * Get followeduser
     *
     * @return Acme\UserBundle\Entity\User 
     */
    public function getFolloweduser()
    {
        return $this->followeduser;
    }

    /**
     * Set followeeuser
     *
     * @param Acme\UserBundle\Entity\User $followeeuser
     */
    public function setFolloweeuser(\Acme\UserBundle\Entity\User $followeeuser)
    {
        $this->followeeuser = $followeeuser;
    }

    /**
     * Get followeeuser
     *
     * @return Acme\UserBundle\Entity\User 
     */
    public function getFolloweeuser()
    {
        return $this->followeeuser;
    }
}

我不确定这是不是可以做到这一点,我真的没有太多时间来测试它,但如果没有,我认为它就在它的路上。我正在使用两种关系,因为你不需要多对多。你需要引用一个用户可以拥有很多关注者,一个关注者可以跟随很多用户,但由于“用户”表是同一个,我做了两个关系,他们与彼此无关,他们只是引用相同的实体,但不同的东西。

尝试并尝试发生的事情。你应该能够做到这样的事情:


$user->getFollowers();

$follower->getFollowedUser();

and you could then check if a user is being followed by a follower whose user_id equals $userThatIwantToCheck

and you could search in Followers for a Follower whose user = $user and followeduser=$possibleFriend