Symfony2 entityManager в модели - PullRequest
11 голосов
/ 10 февраля 2011

Я собираюсь использовать entity_manager в моей модели. Но entity_manager доступен только в контроллере: throw $em = $this->get('doctrine.orm.entity_manager'). Итак, я должен определить методы модели с параметром $em. Это делает тестирование phpUnit довольно сложным и нарушает структуру приложения. Например:

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

Есть ли какой-либо подход к использованию службы entity_manager в разделе модели?

Ответы [ 2 ]

14 голосов
/ 27 мая 2011

Во-первых, начальное примечание: условно ваш класс Entity, вероятно, должен быть единственным.Итак, настройка, а не настройки.Можно утверждать, что «настройки» как группа связанных настроек могут рассматриваться как одна сущность.Тем не менее, кое-что нужно иметь в виду.

В Doctrine2 вы бы использовали хранилище для выполнения запросов такого типа.В вашем коде, где вы собираетесь вызывать Settings::getParam, вы вместо этого извлекаете хранилище и запрашиваете это.В symfony2 скажем:

// $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);

По умолчанию, без написания какого-либо кода, репозитории определяют getByXXXX для каждого поля в вашей сущности.

Если вам нужно выполнить более сложный запрос, вы можете расширить хранилище.

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);
    }

}

И тогда вы бы вызвали этот метод таким же образом.

Другие будут выступать за использование объекта Manager, который затем не будет привязан к Entity / ORM, но я думаю, что в этом случае это является ненужным осложнением.

Doctrine2 специально разработан, чтобы не позволять вам использовать запросы в вашем файле Entity;Entities и EntityManager на самом деле являются двумя аспектами стандартного уровня модели, разделенными для применения передовых методов.Смотрите эту статью: http://symfony2basics.jkw.co.nz/get-symfony2-working/entities/

8 голосов
/ 10 февраля 2011

Запросы в классе сущностей

Ввод запросов в вашу сущность мне кажется странным. Подобно тому, как помещать запросы в класс модели в Doctrine 1, это не считается хорошей практикой. Классы сущностей должны быть легкими.

Я на самом деле изучаю Doctrine2 и думал о схожей проблеме: куда ставить запросы?

В Doctrine 1 есть специальные классы Table, и я ожидал чего-то похожего в Doctrine 2.

Шаблон репозитория

Сегодня я узнал, что Doctrine 2 использует шаблон репозитория: http://www.doctrine -project.org / docs / orm / 2.0 / en / reference / working-with-objects.html # custom-repositories

Однако, чтобы получить экземпляр класса репозитория, вам нужно использовать Entity Manager. Так или иначе, вам это нужно.

Тем не менее, следование шаблону хранилища кажется лучшим выбором.

По моему мнению, если вы настаиваете на наличии метода запроса в вашем классе Entity, вы должны передать ему Entity Manager.

Тестирование

Почему необходимость передачи менеджера сущностей затрудняет тестирование? Из моего опыта явные зависимости облегчают тестирование, так как вы можете контролировать их в тесте (и издеваться над ними, например).

С другой стороны, передача менеджера сущностей каждому методу также не является правильным выбором. В таком случае я бы сделал зависимость обязательной и добавил бы ее в конструктор.

...