tutorial - Las mejores prácticas de Symfony. ¿Las consultas deben estar en repositorios o servicios?
doctrine orm tutorial (2)
Tengo una pregunta sobre las mejores prácticas en Symfony 2. Lo siento si es un poco vago y subjetivo. Supongo que puedo resumir mi pregunta como:
"¿Son los repositorios siempre el lugar correcto para consultas?".
Ahora mismo estoy poniendo la mayoría de mis consultas de doctrina en los repositorios de entidades. La mayoría de las acciones de mi controlador hacen cosas típicas como la consulta de una entidad o colección de entidades, lanzan una excepción o redireccionan según el resultado de eso, de lo contrario actualice una o más entidades. La mayoría de las acciones son más complejas de lo que se puede hacer de manera eficiente con las consultas estándar -> encontrar, -> buscar por etc. La mayoría requiere uniones. Cuando una consulta involucra varias entidades, a veces no estoy seguro de a qué repositorio debería ir. Supongo que existe la entidad raíz de la consulta, pero ... a veces los datos de las entidades unidas son más importantes y relevantes, por lo que se siente mal. para ponerlo en el repositorio de la entidad raíz.
Está funcionando bien, pero tiendo a terminar con muchas consultas similares pero ligeramente diferentes en mis repositorios. Crear nombres y hacer un seguimiento de exactamente lo que hace cada uno puede volverse confuso y tedioso. La mayoría de estas consultas son utilizadas por solo una o dos acciones del controlador en el mismo controlador. Siento que estoy saturando mis repositorios con demasiadas cosas especializadas que rara vez se usan.
Parece que todas las acciones, excepto las más simples, deben encapsularse en un objeto o servicio. Entonces, comencé a hacer muchas de mis consultas directamente en el servicio en lugar de en un repositorio. Es fácil mirar la acción en un solo lugar. ¿Es esta una práctica aceptable?
Puedes hacer algo entre medio.
Definir un servicio:
blog.post_manager:
class: Acme/BlogBundle/Entity/Manager/PostManager
arguments:
em: "@doctrine.orm.entity_manager"
class: Acme/BlogBundle/Entity/Post
Luego crea la clase Manager:
use Doctrine/ORM/EntityManager;
use Doctrine/ORM/EntityRepository;
class PostManager
{
protected $em;
protected $repo;
protected $class;
public function __construct(EntityManager $em, $class) {
$this->em = $em;
$this->class = $class;
$this->repo = $em->getRepository($class);
}
public function get($id)
{
return $this->repo->findById($id);
}
}
De esta manera, aún puede dejar las consultas donde pertenecen, en los repositorios, mientras permite la reutilización del código a través del servicio de administrador que se puede usar así en cualquier controlador:
$this->container->get(''blog.post_manager'')->get(1);
Dado que el servicio se encarga de inyectar la clase y el administrador de entidades a la clase Manager, esto también mantiene al controlador más delgado y mejor lo abstrae del modelo.
Sus consultas deben mantenerse en los repositorios de su entidad y no en sus controladores para poder reutilizarlos fácilmente.
Para eso están los repositorios. Proporcionar una ubicación reutilizable para las consultas de la base de datos.
Sin embargo, hay algunas situaciones en las que se pueden mejorar todas sus consultas en el repositorio ... especialmente cuando se trata de filtrar donde rápidamente se necesitan muchas consultas.
Benjamin Eberlei (creador de Doctrine) considera que 5 métodos públicos en una clase están bien y 10 que son bastante grandes. Recientemente ha publicado un interesante artículo llamado " Sobre la domesticación de las clases de repositorio en Doctrine " sobre este tema en su blog.
En parte me gusta la solución de rasgos de repositorio filtrable de KnpLabs en sus DoctrineBehaviors también.
Los rasgos hacen que las pruebas sean más difíciles, pero puede tener un repositorio más limpio y fácil de mantener ... donde debería mantener sus consultas .