具有自引用多种关系的夹具

时间:2013-11-29 12:24:02

标签: mongodb symfony doctrine-orm fixtures doctrine-odm

我有一个User类,我正在尝试在用户之间实现朋友关系。我遵循了Doctrine的documentation,我认为这种关系很好。我遇到的问题是我无法创建用户夹具,因为我还没有先添加引用。

这是错误消息:

[Symfony\Component\Debug\Exception\ContextErrorException]
  Notice: Undefined index: user-2 in C:\Programming\xampp\htdocs\myProject
  \vendor\doctrine\data-fixtures\lib\Doctrine\Common\DataFixtures\ReferenceRe
  pository.php line 145

这是我的User.php:

namespace MyProject\UserBundle\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints as DoctrineAssert;
use Symfony\Component\Validator\ExecutionContextInterface;

/**
 * @ODM\Document(db="projectdb", collection="users")
 * @ODM\Document(repositoryClass="MyProject\UserBundle\Document\UserRepository")
 * @DoctrineAssert\UniqueEntity("email")
 */
class User implements UserInterface {
    /**
     * @ODM\Id
     */
    private $id;

    /**
     * @ODM\String
     * @Assert\NotBlank(groups={"signUp"})
     * @Assert\Length(min = 6)
     */
    private $password;

    /**
     * @ODM\String
     * @Assert\Email()
     */
    private $email;

    /**
     * @ODM\ReferenceMany(targetDocument="User", mappedBy="myFriends")
     */
    private $friendsWithMe;

    /**
     * @ODM\ReferenceMany(targetDocument="User", inversedBy="friendsWithMe")
     */
    private $myFriends;

    public function __construct()
    {
        $this->friendsWithMe = new \Doctrine\Common\Collections\ArrayCollection();
        $this->myFriends = new \Doctrine\Common\Collections\ArrayCollection();
    }    

    public function getId()
    {
        return $this->id;
    }

    public function setPassword($password)
    {
        $this->password = $password;
        return $this;
    }    

    public function getPassword()
    {
        return $this->password;
    }    

    public function setEmail($email)
    {
        $this->email = $email;
        return $this;
    }

    public function getEmail()
    {
        return $this->email;
    }

    public function getFriendsWithMe()
    {
        return $this->friendsWithMe;
    }

    public function getMyFriends()
    {
        return $this->myFriends;
    }

    public function addFriend(User $user)
    {
        $user->friendsWithMe[] = $this;
        $this->myFriends[]     = $user;
    }

    public function getRoles() {
        return array("ROLE_USER");
    }

    public function eraseCredentials() {

    }

}

这是Users.php(灯具):

namespace Filmboot\MovieBundle\DataFixtures\MongoDB;

use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;

use Filmboot\UserBundle\Document\User;


class Users extends AbstractFixture implements OrderedFixtureInterface {
    public function load(ObjectManager $manager) {
        $users = array(
            array(
                "password"        => "123456a",
                "email"           => "user1@localhost.com",
                "friendsWithMe"   => [$this->getReference("user-2")],
                "myFriends"       => ""),
            array(
                "password"        => "123456b",
                "email"           => "user2@localhost.com",
                "friendsWithMe"   => "",
                "myFriends"       => [$this->getReference("user-1")])
        );

        foreach($users as $i => $user) {
            $i++;
            $document = new User();
            $document->setPassword($user["password"]);
            $document->setEmail($user["email"]);

            foreach ($user["myFriends"] as $friend) {
                $document->addFriend($friend);
            }

            $manager->persist($document);
            $this->addReference("user-" . $i, $document);

        }

        $manager->flush();
    }

    public function getOrder() {
        return 0;
    }
}

2 个答案:

答案 0 :(得分:0)

我没有对此进行过测试,因此它可能有点错误,但是您应该能够看到我已经引用了引用键而不是引用本身,然后在创建用户之后,执行友谊映射后。

class Users extends AbstractFixture implements OrderedFixtureInterface {
    public function load(ObjectManager $manager) {
        $users = array(
            'user-1' => array(
                "password"        => "123456a",
                "email"           => "user1@localhost.com",
                "friendsWithMe"   => array('user-2'),
                "myFriends"       => ""),
            'user-2' => array(
                "password"        => "123456b",
                "email"           => "user2@localhost.com",
                "friendsWithMe"   => "",
                "myFriends"       => array('user-1'))
        );

        $friendships = array();

        foreach($users as $i => $user) {
            $i++;
            $document = new User();
            $document->setPassword($user["password"]);
            $document->setEmail($user["email"]);

            foreach ($user["myFriends"] as $friend) {
                $friendships[$i][] = $friend;
            }

            $manager->persist($document);
            $this->addReference($i, $document);

        }

        foreach($friendships as $k => $v) {
            $user = $this->getReference($k);
            $friend = $this->getReference($v);

            $user->addFriend($friend->addFriend($user));
        }

        $manager->flush();
    }

    public function getOrder() {
        return 0;
    }
}

答案 1 :(得分:0)

我找到了解决问题的方法。我已从inversedBy移除$myFriends,从mappedBy移除$friendsWithMe。然后,在灯具中我首先添加所有用户,其次我让每个用户添加他的朋友。

foreach($users as $i => $user) {
    $i++;
    $ref = $this->getReference($i);
    foreach($user['myFriends'] as $friend) {
        $ref->addFriend($this->getReference($friend));
    }
}