Liudas Butkus
Liudas Butkus

Reputation: 198

ManyToMany Relationship With Type Symfony Doctrine

I have this structure of Entities

class Group
{
    /**
     * @var int
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private int $id;

    /**
     * @var string
     * @ORM\Column(name="name", type="string", length=50, nullable=false)
     */
    private string $name;
}


class GroupUser
{
    /**
     * @var int
     *
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private int $id;

    /**
     * @var Group
     * @ORM\ManyToOne(targetEntity="Group", inversedBy="GroupUser")
     * @ORM\JoinColumn(name="group_id", referencedColumnName="id", nullable=false)
     */
    private Group $group;

    /**
     * @var string
     * @ORM\Column(type="string", length=50, nullable=false)
     */
    private string $type;

    /**
     * @var int
     * @ORM\Column(type="integer", nullable=false)
     */
    private int $user;

}

And there are two types of users. Admins and Clients. There's a ManyToMany relationship between Group and User. And the property in GroupUser $type is saving the Class of either Admin or Client and the property $user is saving the id.

id group_id user type
1 1 1 Entity\Admin
2 2 1 Entity\Client

How do I join it using doctrine from the Admin and Client-side? Or maybe someone could point out to some resources how this kind of relationship works on doctrine? As I'm having a hard time googling anything out. I imagine it could be like a conditional leftJoin, but I can't seem to figure it out.

Upvotes: 0

Views: 1026

Answers (1)

Florent Cardot
Florent Cardot

Reputation: 1418

Normaly, you cannot do that on database, because it not safe. Why is it not safe? because you can have an id in the user column of userGroup table that refer to nothing as it is not linked.

I will write what you should have done, and how you can achieve what you want using your own method:

What you should have done: In your UserGroup entities, have 2 columns (admin and client) which are linked to the related entities. They can be null (Client is null and admin contain the id of admin entity if it is an admin and vice versa). Then you can delete the type column

How to achieve what you using your method: As it cannot be done in the database, you will have to do it in some manager. Have a method getUser which will check on your type attribute and return the associated entity from the current id stored in $user

example:

    public function getUserFromGroupUser(GroupUser $groupUser){
        if('Entity\Admin' ===$groupUser->getType()){
            return $this->adminRepository->find($groupUser->getUser());
        }
        if('Entity\Client' ===$groupUser->getType()){
            return $this->ClientRepository->find($groupUser->getUser());
        }
        throw new \RuntimeException('the type does not exist');
    }

Upvotes: 1

Related Questions