title: Symfony 4 - Define custom user roles from DB
body: <p>I am learning Symfony 4, and I am lost with user roles and I don't know where to start.
  Because it will be an intranet like website Users will not register themselves, the admin will register them and set the role. The admin can also create new roles dynamically.
  I would like to store user roles in database. I have 2 entities <code>User</code> and <code>Role</code>. (Relations are not defined yet, that´s normal)</p>
  
  <p>Here is my <code>User</code> entity : </p>
  
  <pre><code>&lt;?php
  
  namespace App\Entity;
  
  use Doctrine\ORM\Mapping as ORM;
  use Symfony\Component\Validator\Constraints as Assert;
  use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
  use Symfony\Component\Security\Core\User\UserInterface;
  
  /**
   * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
   * @UniqueEntity(fields="email", message="Email already taken")
   * @UniqueEntity(fields="username", message="Username already taken")
   */
  class User implements UserInterface, \Serializable
  {
      /**
       * @ORM\Id
       * @ORM\GeneratedValue(strategy="AUTO")
       * @ORM\Column(type="integer", unique=true)
       */
      private $id;
  
      /**
      * @ORM\Column(type="string", length=255)
      */
      private $firstname;
  
      /**
       * @ORM\Column(type="string", length=255)
       */
      private $lastname;
  
      /**
       * @ORM\Column(type="string", length=255)
       */
      private $email;
  
      /**
       * @ORM\Column(type="date")
       */
      private $birthdate;
  
      /**
       * @ORM\Column(type="integer", nullable=true)
       */
      private $roleId;
  
      /**
       * @ORM\Column(type="string", length=255, nullable=false)
       */
      private $username;
  
      /**
       * @Assert\NotBlank()
       * @Assert\Length(max=4096)
       */
      private $plainPassword;
  
      /**
       * @ORM\Column(type="string", length=255, nullable=false)
       */
      private $password;
  
      /**
       * @ORM\Column(name="is_active", type="boolean", nullable=true)
       */
      private $isActive;
  
      // GETTERS
  
      public function getId()
      {
          return $this-&gt;id;
      }
  
      public function getFirstname()
      {
          return $this-&gt;firstname;
      }
  
      public function getLastname()
      {
          return $this-&gt;lastname;
      }
  
      public function getBirthdate()
      {
          return $this-&gt;birthdate;
      }
  
      public function getEmail()
      {
          return $this-&gt;email;
      }
  
      public function getRoleId()
      {
          return $this-&gt;roleId;
      }
  
      public function getRoles()
      {
          return array('ROLE_USER');
      }
  
      public function getUsername()
      {
        return $this-&gt;username;
      }
  
      public function getPlainPassword()
      {
          return $this-&gt;plainPassword;
      }
  
      public function getPassword()
      {
        return $this-&gt;password;
      }
  
      public function getSalt()
      {
       return null;
      }
  
      // SETTERS
  
      public function setFirstname($firstname)
      {
          $this-&gt;firstname = $firstname;
      }
  
      public function setLastname($lastname)
      {
          $this-&gt;lastname = $lastname;
      }
  
      public function setEmail($email)
      {
          $this-&gt;email = $email;
      }
  
      public function setBirthdate($birthdate)
      {
          $this-&gt;birthdate = $birthdate;
      }
  
      public function setRoleId($roleId)
      {
          $this-&gt;roleId = $roleId;
      }
  
      public function setUsername($username)
      {
          $this-&gt;username = $username;
      }
  
      public function setPlainPassword($password)
      {
          $this-&gt;plainPassword = $password;
      }
  
  
      public function setPassword($password)
      {
          $this-&gt;password = $password;
      }
  
      // FUNCTIONS
  
      public function serialize()
      {
          return serialize(array(
              $this-&gt;id,
              $this-&gt;username,
              $this-&gt;password,
              // see section on salt below
              // $this-&gt;salt,
          ));
      }
  
      /** @see \Serializable::unserialize() */
      public function unserialize($serialized)
      {
          list (
              $this-&gt;id,
              $this-&gt;username,
              $this-&gt;password,
              // see section on salt below
              // $this-&gt;salt
          ) = unserialize($serialized);
      }
  
      public function eraseCredentials()
      {
  
      }
  }
  </code></pre>
  
  <p>Here is my <code>Role</code> entity : </p>
  
  <pre><code>&lt;?php
  
  namespace App\Entity;
  
  use Doctrine\ORM\Mapping as ORM;
  
  /**
   * @ORM\Entity(repositoryClass="App\Repository\RoleRepository")
   */
  class Role
  {
      /**
       * @ORM\Id
       * @ORM\GeneratedValue
       * @ORM\Column(type="integer", unique=true)
       */
      private $id;
  
      /**
       * @ORM\Column(type="string", length=255, nullable=false)
       */
      private $type;
  
      // GETTERS
  
      public function getId()
      {
          return $this-&gt;id;
      }
  
      public function getType()
      {
          return $this-&gt;type;
      }
  
      // SETTERS
  
      public function setType($type): void
      {
          $this-&gt;type = $type;
      }
  }
  </code></pre>
  
  <p>Is it a good practice to do so ??</p>
  
  <p>On the Symfony documentation, we can read everywhere the "macros" <code>ROLE_USER</code>, <code>ROLE_ADMIN</code>... Where are they defined ? Can we customize this ?</p>