0

I have a problem with my many to many relations

I have a User class that can be on multiple Teams and a class Team that can have multiple Users

class User

    /**
     * @var Collection
     * @ODM\ReferenceMany(
     *     targetDocument="App\Model\Document\Team",
     *     mappedBy="members",
     *     strategy="setArray"
     * )
     */
    protected $teams;

class Team

    /**
     * @var Collection|null
     * @ODM\ReferenceMany(
     *     targetDocument="App\Model\Document\User",
     *     inversedBy="teams",
     *     strategy="setArray",
     *     sort={"username": "asc"},
     *     cascade={"persist"}
     * )
     */
    protected $members;

With these annotations, when I add members User to the team and I do a getMembers on an instance of Team, it works. BUT, when I have an instance of a User (that's a member of a Team) the getTeams return nothing (empty PersistentCollection)

The reference is stored on the Teams Document, as an array of references

"members" : [ 
    {
        "$ref" : "User",
        "$id" : ObjectId("XXX"),
        "$db" : "readDat"
    }
],

I don't understand, with the annotations as they are now, I thought Doctrine would do something like this db.getCollection('Team').find({"members.$id":ObjectId("XXX")}) to have the teams but it seems not.

On the other hand, I tried to inverse the mappedBy and inversedBy, I can't even getMembers (on a Team object) or getTeams (on a User object) anymore, both are empty Collection.

How can I have a good Many to Many (without duplicate the references in both Document) ?

Etshy
  • 870
  • 7
  • 25
  • 1
    Have you used $teams = $user->getTeams()->toArray();? – iiirxs Oct 01 '18 at 23:12
  • Wow, seems it works, thank you !. Dunno why my twig foreach and my `dump` don't see the elements, but with `dump($user->getTeams()->toArray())` I see my team. I'll change my twig to use toArray as well. I still don't understand why it's empty if I don't add the toArray. – Etshy Oct 01 '18 at 23:31
  • 1
    It's about lazy hydration. Your collection is not initialized until it has to. When you call toArray() in fact you force the collection to get initialized. – iiirxs Oct 01 '18 at 23:36
  • Oh okay, I had no idea about that. Is there a proper way to force the collection to be initialized while keeping the Collection class instance ? Maybe it's not good idea though, but If I can stay with ArrayCollection, I can have all the ArrayCollection methods. I can stil create a new ArrayCollection like this though `new ArrayCollection($user->getTeams()->toArray())` but that's not "clean", imo. – Etshy Oct 02 '18 at 07:41
  • @Etshy just don't (var_)dump the collection, use it normally (i.e. foreach over it, filter or any other method from the `Collection` interface) and it will work – malarzm Oct 02 '18 at 08:10
  • @malarzm I'm not sure it works in twig. Before I change my twig to `{% for team in user.teams.toArray %}` nothing was shown. Maybe in Php, it could works though. I'll do more tests on my free time later. – Etshy Oct 02 '18 at 08:33

0 Answers0