Vincent PHILIPPE
Vincent PHILIPPE

Reputation: 1191

Add PersistentCollection to an object in fixture

I'm trying to create a new fixture for creating a user.

This is the fixture :

class UserFixtures extends Fixture implements DependentFixtureInterface
{
    private ManagerRegistry $_managerRegistry;

    public function __construct(ManagerRegistry $managerRegistry)
    {
        $this->_managerRegistry = $managerRegistry;
    }

    public function load(ObjectManager $manager)
    {
        $groups = $manager->getRepository(Group::class)->findAll(); // This return an array of object. I want a PersistentCollection
        $company = $manager->getRepository(Company::class)->findOneBy(['company_name' => 'HANFF - Global Health Solution']);
        $user = new User();
        $user->setLogin("TEST_TEST")
             ->setName("TEST_Name")
             ->setFirstName("TEST_Firstname")
             ->setPassword("test")
             ->setEmail("[email protected]");
        $user->setCompany($company);
        $user->setGroups($groups); // This don't work as it is just an array
        $manager->persist($user);
        $manager->flush();
    }

    /**
     * @inheritDoc
     */
    public function getDependencies()
    {
        return array(
                CompanyFixture::class,
                GroupFixture::class
        );
    }
}

So I have already created the company and group which persist into my database. And now I want to set to my new user the company and group which have been previously persisted by doctrine.

This work for my company as this is a single object. But this is not working for my groups as it is typed as a PersistenCollection object and the getRepository(Group::class)->findAll() return an array of object Group.

Here the data contains in the $groups variable :

array:2 [
  0 => App\Entity\Group {#1039
    -code: "NAT"
    -label: "National"
  }
  1 => App\Entity\Group {#1044
    -code: "VET"
    -label: "Vétérinaire"
  }
]

Here this is how I defined the groups into my User entity :

Class User{
  //    ...
  /**
     * @var PersistentCollection
     * Many user has many groups
     * @ORM\ManyToMany(targetEntity="Group")
     * @ORM\JoinTable(name="user_group",
     *      joinColumns={@ORm\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="group_code", referencedColumnName="`code`")}
     *      )
     */
    private PersistentCollection $groups;

    public function getGroups(): PersistentCollection
    {
        return $this->groups;
    }

    public function setGroups(PersistentCollection $groups): self
    {
        $this->groups = $groups;
        return $this;
    }

    public function addGroup($group): self
    {
        $this->getGroups()->add($group);
        return $this;
    }
    
    //     ...
}

I have read somewhere (can't remember where) that when you persist an object using doctrine, it can be accessed as a PersistentCollection but I can't figure how to do that (Except by creating a new PersistentCollection() which is certainly not the best manner to do it)?

I have tried setting ArrayCollection instead of PersistentCollection, but if I do that, doctrine yells at me when I try to persist my user object because it can't convert ArrayCollection to PersistentCollection (i guess).

Upvotes: 3

Views: 566

Answers (1)

Philip Weinke
Philip Weinke

Reputation: 1844

You have to change the types of your properties, arguments and return values to the Doctrine\Common\Collections\Collection interface. That's the interface ArrayCollection and PersistentCollection share. Don't forget to initialize your groups property to an ArrayCollection in the constructor. Otherwise calls to addGroup will fail on new user entities.

class User
{
  //    ...
  /**
     * @ORM\ManyToMany(targetEntity="Group")
     * @ORM\JoinTable(name="user_group",
     *      joinColumns={@ORm\JoinColumn(name="user_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="group_code", referencedColumnName="`code`")}
     *      )
     */
    private Collection $groups;

    public function __construct()
    {
        // other initialization
        $this->groups = new ArrayCollection();
    }

    public function getGroups(): Collection
    {
        return $this->groups;
    }

    public function setGroups(Collection $groups): self
    {
        $this->groups = $groups;
        return $this;
    }

    public function addGroup($group): self
    {
        $this->getGroups()->add($group);
        return $this;
    }
    
    //     ...
}

Upvotes: 5

Related Questions