@@ -561,8 +561,8 @@ In this example, the ``AcmeUserBundle:User`` entity class defines a
561
561
many-to-many relationship with a ``AcmeUserBundle:Role`` entity class.
562
562
A user can be related to several roles and a role can be composed of
563
563
one or more users. The previous ``getRoles()`` method now returns
564
- the list of related roles.
565
- Notice that methods ``__construcotor()`` and ``getRoles()`` had changed::
564
+ the list of related roles. Notice that ``__construct()`` and ``getRoles()``
565
+ methods have changed::
566
566
567
567
// src/Acme/UserBundle/Entity/User.php
568
568
namespace Acme\UserBundle\Entity;
@@ -572,7 +572,7 @@ Notice that methods ``__construcotor()`` and ``getRoles()`` had changed::
572
572
573
573
class User implements AdvancedUserInterface, \Serializable
574
574
{
575
- //...
575
+ // ...
576
576
577
577
/**
578
578
* @ORM\ManyToMany(targetEntity="Role", inversedBy="users")
@@ -594,11 +594,10 @@ Notice that methods ``__construcotor()`` and ``getRoles()`` had changed::
594
594
595
595
}
596
596
597
- The ``AcmeUserBundle:Role`` entity class defines three table fields (``id``,
598
- ``name`` and ``role``). The unique ``role`` field contains the role name used by
599
- the Symfony security layer to secure parts of the application. The most
600
- important thing to notice is that the ``AcmeUserBundle:Role`` entity class
601
- extends the :class:`Symfony\\Component\\Security\\Core\\Role\\Role`::
597
+ The ``AcmeUserBundle:Role`` entity class defines three fields (``id``,
598
+ ``name`` and ``role``). The unique ``role`` field contains the role name
599
+ (e.g. ``ROLE_ADMIN``) used by the Symfony security layer to secure parts
600
+ of the application::
602
601
603
602
// src/Acme/Bundle/UserBundle/Entity/Role.php
604
603
namespace Acme\UserBundle\Entity;
@@ -651,14 +650,63 @@ extends the :class:`Symfony\\Component\\Security\\Core\\Role\\Role`::
651
650
// ... getters and setters for each property
652
651
}
653
652
654
- .. tip::
653
+ For brevity, the getter and setter methods are hidden, but you can
654
+ :ref:`generate them <book-doctrine-generating-getters-and-setters>`:
655
+
656
+ .. code-block:: bas
657
+
658
+ $ php app/console doctrine:generate:entities Acme/UserBundle/Entity/User
659
+
660
+ Don' t forget also to update your database schema:
661
+
662
+ .. code-block:: bash
663
+
664
+ php app/console doctrine:schema:update --force
665
+
666
+ This will create the ` ` acme_role` ` table and a ` ` user_role` ` that stores
667
+ the many-to-many relationship between ` ` acme_user` ` and ` ` acme_role` ` . If
668
+ you had one user linked to one role, your database might look something like
669
+ this:
670
+
671
+ .. code-block:: text
672
+
673
+ $ mysql> select * from acme_users;
674
+ +----+-------+------------+
675
+ | id | name | role |
676
+ +----+-------+------------+
677
+ | 1 | admin | ROLE_ADMIN |
678
+ +----+-------+------------+
679
+
680
+ mysql> select * from user_role;
681
+ +---------+---------+
682
+ | user_id | role_id |
683
+ +---------+---------+
684
+ | 1 | 1 |
685
+ +---------+---------+
686
+
687
+ And that' s it! When the user logs in, Symfony security system will call the
688
+ ``User::getRoles`` method. This will return an array of ``Role`` objects
689
+ that Symfony will use to determine if the user should have access to certain
690
+ parts of the system.
691
+
692
+ .. sidebar:: What' s the purpose of the RoleInterface?
655
693
656
- To generate missing setters and getters for your ``Role`` entity, you
657
- can use ``php app/console doctrine:generate:entities Acme/UserBundle/Entity/User``.
658
- For more details, see Doctrine' s :ref:` book-doctrine-generating-getters-and-setters` .
694
+ Notice that the ` ` Role` ` class implements
695
+ :class:` Symfony\\ Component\\ Security\\ Core\\ Role\\ RoleInterface` . This is
696
+ because Symfony' s security system requires that the ``User::getRoles`` method
697
+ returns an array of either role strings or objects that implement this interface.
698
+ If ``Role`` didn' t implement this interface, then ` ` User::getRoles` `
699
+ would need to iterate over all the ` ` Role` ` objects, call ` ` getRole` `
700
+ on each, and create an array of strings to return. Both approaches are
701
+ valid and equivalent.
659
702
660
- To improve performances and avoid lazy loading of roles when retrieving a user
661
- from the custom entity provider, the best solution is to join the roles
703
+ .. _cookbook-doctrine-entity-provider-role-db-schema:
704
+
705
+ Improving Performance with a Join
706
+ ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
707
+
708
+ To improve performance and avoid lazy loading of roles when retrieving a user
709
+ from the custom entity provider, you can use a Doctrine join to the roles
662
710
relationship in the ``UserRepository::loadUserByUsername ()` ` method. This will
663
711
fetch the user and his associated roles with a single query::
664
712
@@ -689,26 +737,3 @@ fetch the user and his associated roles with a single query::
689
737
The ``QueryBuilder::leftJoin ()` ` method joins and fetches related roles from
690
738
the ` ` AcmeUserBundle:User` ` model class when a user is retrieved with his email
691
739
address or username.
692
-
693
- To re-generate all database tables, you can run ` ` php app/console doctrine:schema:update --force` ` .
694
- This will also create additional table ` ` user_role` ` what holds
695
- relations between users and roles.
696
- For mor details, see Doctrine' s :ref:`book-doctrine-creating-the-database-tables-schema`.
697
-
698
- Below is an export of my ``Roles`` and ``user_role`` tables from MySQL:
699
-
700
- .. code-block:: bash
701
-
702
- $ mysql> select * from acme_users;
703
- +----+-------+------------+
704
- | id | name | role |
705
- +----+-------+------------+
706
- | 1 | admin | ROLE_ADMIN |
707
- +----+-------+------------+
708
-
709
- mysql> select * from user_role;
710
- +---------+---------+
711
- | user_id | role_id |
712
- +---------+---------+
713
- | 1 | 1 |
714
- +---------+---------+
0 commit comments