Symfony2 entityManager in model

Aleksei Kornushkin picture Aleksei Kornushkin · Feb 10, 2011 · Viewed 12.3k times · Source

I'm going to use entity_manager in my model. But entity_manager is only available in controller: throw $em = $this->get('doctrine.orm.entity_manager'). So, I have to define model methods with $em parameter. This is making phpUnit testing pretty difficult and violates application structure. For example:

class Settings
{
    public static function getParam( $em, $key )
    {
        $em->createQuery("
            SELECT s
            FROM FrontendBundle:Settings s
            WHERE s.param = {$key}
        ");
        return $em->getResult();
    }
}

Is there any approach to use entity_manager service in model section?

Answer

Jeremy Warne picture Jeremy Warne · May 27, 2011

First, a starting note: by convention your Entity class should probably be singular. So, Setting, not Settings. You could argue that "settings" as a group of related settings could be seen as one entity. Still, something to bear in mind.

In Doctrine2, you would use a repository to make this type of query. In your code where you were going to call Settings::getParam, you would instead fetch the repository and query that. In symfony2, say:

// $em is your entitymanager, as you were going to pass to your method above
// $key is the key you were going to pass to your method above
$repository = $em->getRepository('\FrontendBundle\Settings');
$setting = $repository->getByParam($key);

By default, without writing any code, repositories define getByXXXX for each field in your entity.

If you have a more complicated query to make, you can extend the repository.

use Doctrine\ORM\EntityRepository;

class SettingsRepository extends EntityRepository 
{
    public function getBySomeComplicatedQuery() {
        $sort_order = $this->getEntityManager()
            ->createQuery('SELECT count(s) FROM FrontendBundle\Settings s WHERE s.value > 32')
            ->getResult(Query::HYDRATE_SINGLE_SCALAR);
    }

}

And then you'd call that method in the same way.

Others would advocate the use of a Manager object which would then not be tied to the Entity/ORM, but that's a needless complication in this case I think.

Doctrine2 is specifically designed to not let you use queries in your Entity file; Entities and EntityManagers are actually two aspects of the standard model layer, split apart to enforce best practices. See this article: http://symfony2basics.jkw.co.nz/get-symfony2-working/entities/