Я уже рассматривал в одной из прошлых статей случайные выборки (см.). Сейчас мы самым простым способом интегрируем получение случайной записи в Symfony2 проект при помощи Doctrine2 Repository.
Мои entities определены по привычке в YAML формате, поэтому я буду описывать именно его. Итак, укажем нашей сущности использовать кастомный Repository:
# src/Vendor/MyBundle/Resources/config/doctrine/metadata/orm/Vendor.MyBundle.Entity.User.dcm.yml Vendor\MyBundle\Entity\User: type: entity table: user ... repositoryClass: Vendor\MyBundle\Repository\UserRepository ... |
После этого можно создать класс UserRepository.php
в директории src/Vendor/MyBundle/Repository
или же выполнить команду doctrine:generate:repositories
:
>php app\console doctrine:generate:repositories VendorMyBundle Generating entity repositories for "VendorMyBundle" > OK generating Vendor\MyBundle\Repository\UserRepository > SKIP no custom repository for Vendor\MyBundle\Entity\UserData |
У нас есть класс репозитория. Добавим в него метод выбора случайного юзера:
public function getRandomUser() { // mapper для результата $rsm = new ResultSetMapping; $rsm->addEntityResult('Vendor\MyBundle\Entity\User', 'u'); $rsm->addFieldResult('u', 'id', 'id'); // тут я использую NativeQuery - перевести этот запрос в DQL для меня сейчас слабо ) // также примем допущение что user не содержит "дыр" в ID $query = $this->getEntityManager()->createNativeQuery( 'SELECT id FROM user JOIN ( SELECT CEIL(RAND() * (SELECT MAX(id) FROM user)) AS id ) AS r2 USING (id)', $rsm ); // ищем случайный ID $user = $query->getSingleResult(); // на выходе получаем полноценный Vendor\MyBundle\Entity\User (хотя как вариант можно написать маппер на все необходимые поля) return $this->find($user->getId()); } |
В контроллере пользуемся репозиторием так:
public function someAction() { $em = $this->get('doctrine.orm.entity_manager'); $userRepo = $em->getRepository('VendorMyBundle:User'); $randomUser = $userRepo->getRandomUser(); } |
P.S. данный код возможно далек от идеала, тем не менее на пробную работу с репозиторием и native sql мной было потрачено некоторое время, результатами своих изысканий я с вами и делюсь )
А класс сущности генерится автоматом?
Да, автоматом. Пока не нашел плюсов в аннотациях – кроме того что они более всего документированы.
Мне нравится валидацию описывать аннотациями.
Я имел в виду именно сущности ) Валидация по-моему альтернативного способа и не предполагает. Во всяком случае это не документировано
Валидация предлагает такие же варианты как и маппинг для доктрины: xml, yaml, annotations, static php method.
Плюсы аннотаций:
1) можно скрыть в IDE – Ъ
2) сущность и описание ее маппинга в одном месте.
зы: а есть ли какая-то регистрация на сайте? Надоело капчу вводить, да и посты хочу править если что.
По сабжу: а что если это дело вынести в сервисный слой, и метод будет возвращать не HydratedResult а объект QueryBuilder’а, где я смогу заджоинить нужные мне колонки к юзеру, или вообще получить какие-то другие данные на основе этого подзапроса?
Ну по факту entity manager это тоже вроде бы служба, так что не вижу препятствий – хотя конечно надо попробовать. А вот необходимость такого решения лично для меня под вопросом – посуди сам, я получаю репозиторий так же как службу, просто на выходе метода не результаты выборки а QueryBuilder.
Насчет регистрации посмотрю – у меня мультисайт не хочу блоги плодить )) хотя если хочешь тоже покарябать статьи – для тебя – сделаю )
Меня максимум на комментарии хватает :Р.
Окей, я посмотрю что там надо для регистрации замутить чтобы блог не создавался.
Вроде открыл регистрацию, будет время – глянь ) http://hudson.su/wp-signup.php
> php app\console doctrine:generate:repositories …
Выводит ошибку
[InvalidArgumentException]
Command “doctrine:generate:repositories” is not defined.
Did you mean one of these?
doctrine:generate:entities
doctrine:generate:entity
doctrine:generate:form
Уважаемый, это статья более чем полуторагодичной давности. Для версии Симфони 2.0.х, версию Doctrine не помню. Для начала рекомендую изучить следующие команды:
c:\openserver\__src\repo>php app/console list doctrine
Symfony version 2.1.7-DEV – app/dev/debug
Available commands for the “doctrine” namespace:
doctrine:cache:clear-metadata
doctrine:cache:clear-query
doctrine:cache:clear-result
doctrine:database:create
doctrine:database:drop
doctrine:ensure-production-settings
doctrine:fixtures:load
doctrine:generate:crud
doctrine:generate:entities
doctrine:generate:entity
doctrine:generate:form
doctrine:mapping:convert
doctrine:mapping:import
doctrine:mapping:info
doctrine:migrations:diff
doctrine:migrations:execute
doctrine:migrations:generate
doctrine:migrations:migrate
doctrine:migrations:status
doctrine:migrations:version
doctrine:query:dql
doctrine:query:sql
doctrine:schema:create
doctrine:schema:drop
doctrine:schema:update
doctrine:schema:validate
Если же говорить о репозиториях, то они насколько я знаю, создаются при выполнении команды doctrine:generate:entities (если кастомный репозиторий прописан в сущности)
Мне кажется самый простой метод достать рандомную запись это:
$this->em->getRepository('вашБандл:вашРепозиторий') ->findOneBy([]);
Возвращает всегда первую запись…