Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Additional fields in ORM-ManyToMany relation

I have following tables with data: Users and Groups. In my database relation between this two entities is ManyToMany, because many users can be in many groups and many groups can have many users. This is simple. I created this code and it works:

User Entity:

/**
 * @ORM\Entity
 * @ORM\Table(name="users")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToMany(targetEntity="Group", inversedBy="users")
     * @ORM\JoinTable(name="users_in_groups")
     */
    protected $groups;
}

Group Entity:

/**
 * @ORM\Entity
 * @ORM\Table(name="groups")
 */
class Group
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToMany(targetEntity="User", mappedBy="groups")
     */
    protected $users;
}

Symfony created three tables: users, groups and users_in_groups. Everything work great, but I want to set different permissions for different users in each group. For example: User1 is admin in Group1 and standard member in Group2, etc. The best solution could be insert new field to users_in_groups but this table was created by @ORM\JoinTable function and I don't know how can I do that. Do you know simple solution for this problem?

like image 594
ZaquPL Avatar asked Mar 16 '15 22:03

ZaquPL


2 Answers

The simpliest way to do this that I've found is to use a third entity

Here's how it would work in your case

User entity :

/**
 * @ORM\Entity
 * @ORM\Table(name="users")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

   /**
     * @ORM\OneToMany(targetEntity="UserGroup", mappedBy="user")
     * */
    protected $usergroup;
}

Group Entity :

/**
 * @ORM\Entity
 * @ORM\Table(name="groups")
 */
class Group
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
      * @ORM\OneToMany(targetEntity="UserGroup" , mappedBy="group"})
     * */
    protected $usergroup;
}

UserGroup Entity:

/**
 * @ORM\Entity
 * @ORM\Table(name="user_group")
 */
class UserGroup
{

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     *
     * @var integer $id
     */
    protected $id;


    /**
     * @ORM\ManyToOne(targetEntity="User", inversedBy="usergroup")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     * */
    protected $user;

    /**
     * @ORM\ManyToOne(targetEntity="Group", inversedBy="usergroup")
     * @ORM\JoinColumn(name="group_id", referencedColumnName="id")
     * */
    protected $group;


    // Additional fields, Getter, Setters, _Construct, __toString 


}
like image 150
BentoumiTech Avatar answered Nov 07 '22 17:11

BentoumiTech


Take a look at the documentation on ManyToMany relationships.

Why are many-to-many associations less common? Because frequently you want to associate additional attributes with an association, in which case you introduce an association class. Consequently, the direct many-to-many association disappears and is replaced by one-to-many/many-to-one associations between the 3 participating classes.

So in other words, as soon as you want attributes on a relationship table, it's no longer just a relationship table. It needs it own entity. That new entity now gets one-to-many/many-to-one relationships with users and groups.

Then you can use the Composite and Foreign Keys as Primary Key feature in your new entity.

Some past discussion on this topic: https://groups.google.com/forum/#!topic/doctrine-user/0dh8lgUudvc

like image 45
JoeCoder Avatar answered Nov 07 '22 18:11

JoeCoder