Skip to content

Commit c10c405

Browse files
committed
[#2765] Reading through and refactoring changes to the entity_provider entry
1 parent 7a37651 commit c10c405

File tree

1 file changed

+62
-37
lines changed

1 file changed

+62
-37
lines changed

cookbook/security/entity_provider.rst

+62-37
Original file line numberDiff line numberDiff line change
@@ -561,8 +561,8 @@ In this example, the ``AcmeUserBundle:User`` entity class defines a
561561
many-to-many relationship with a ``AcmeUserBundle:Role`` entity class.
562562
A user can be related to several roles and a role can be composed of
563563
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::
566566
567567
// src/Acme/UserBundle/Entity/User.php
568568
namespace Acme\UserBundle\Entity;
@@ -572,7 +572,7 @@ Notice that methods ``__construcotor()`` and ``getRoles()`` had changed::
572572
573573
class User implements AdvancedUserInterface, \Serializable
574574
{
575-
//...
575+
// ...
576576
577577
/**
578578
* @ORM\ManyToMany(targetEntity="Role", inversedBy="users")
@@ -594,11 +594,10 @@ Notice that methods ``__construcotor()`` and ``getRoles()`` had changed::
594594
595595
}
596596
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::
602601
603602
// src/Acme/Bundle/UserBundle/Entity/Role.php
604603
namespace Acme\UserBundle\Entity;
@@ -651,14 +650,63 @@ extends the :class:`Symfony\\Component\\Security\\Core\\Role\\Role`::
651650
// ... getters and setters for each property
652651
}
653652
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?
655693
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.
659702
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
662710
relationship in the ``UserRepository::loadUserByUsername()`` method. This will
663711
fetch the user and his associated roles with a single query::
664712
@@ -689,26 +737,3 @@ fetch the user and his associated roles with a single query::
689737
The ``QueryBuilder::leftJoin()`` method joins and fetches related roles from
690738
the ``AcmeUserBundle:User`` model class when a user is retrieved with his email
691739
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

Comments
 (0)