У меня есть объект продукта, в котором у него есть массив в качестве атрибутов:
/** * @ORM\OneToMany(targetEntity="Shopious\MainBundle\Entity\ProductPicture", mappedBy="product", cascade={"persist","remove"}) */ protected $pictures; /** * @Accessor(getter="getCover") */ private $cover; public function getCover() { if($this->pictures->count() > 0) { return $this->pictures[0]; } return new ProductPicture(); }
Теперь в моем построителе запросов у меня есть следующий код:
$query = $em->createQueryBuilder()->select('p') ->from("SiteMainBundle:Product", 'p') ->innerJoin('p.category', 'c') ->innerJoin('p.shop', 'shop') ;
Проблема здесь в том, что я не хочу выбирать все атрибуты p. Поэтому я только хотел получить первый ProductPicture в массиве изображений (в моем случае выше он похож на метод getCover ()). Как мне это сделать?
Пока я могу отфильтровать частичные атрибуты, которые я хочу сделать:
$query = $em->createQueryBuilder()->select('p.name, p.id') ->from("SiteMainBundle:Product", 'p') ->innerJoin('p.category', 'c') ->innerJoin('p.shop', 'shop') ->innerJoin('p.pictures', 'pictures') ;
поэтому в приведенном выше примере я сделал внутреннее присоединение к изображениям, но как мне получить первый элемент отсюда?
В заключение, мой вопрос: как выбрать / запросить первый ProductPicture в массиве изображений с помощью построителя запросов? Потому что, когда я это делаю:
$ query = $ em-> createQueryBuilder () -> select ('p')
он возвращает все атрибуты продукта, но мне не нужны все атрибуты продукта. Мне нужны только некоторые из них, такие как идентификатор, имя и т. д. Однако один из атрибутов продукта – это сущность (которая является продуктом ProductPicture ), так как я могу вернуть это в инструкции select?
РЕДАКТИРОВАТЬ:
Вот эквивалент SQL, по которому должны быть связаны снимки:
SELECT * FROM `product` JOIN `product_picture` ON `product`.id = `product_picture`.product_id WHERE `product`.id =100 LIMIT 1
Попробуйте что-то вроде этого, если это один ко многим, нормальное поведение mySQL возвращает несколько записей с избыточными данными продукта, если один и тот же случай происходит здесь, то только возврат первой записи должен сделать трюк.
PS : если объект ProductPicture имеет свойство url, которое вы хотите получить
$query = $em->createQueryBuilder()->select('p.id, p.name, pictures.url') ->from("SiteMainBundle:Product", 'p') ->innerJoin('p.category', 'c') ->innerJoin('p.shop', 'shop') ->innerJoin('p.pictures', 'pictures') ;
Добавьте собственный метод репозитория с DQL для вашей сущности, затем вызовите его с контроллера
Вы можете назвать метод репозитория любым findProductWithPicture
, для этого примера я использую findProductWithPicture
class ProductRepository extends EntityRepository { /** * @param integer $id */ public function findProductWithPicture($id) { $dql = <<<SQL SELECT p.id id, p.name name, q picture FROM Shopious\MainBundle\Entity\ProductPicture q, Shopious\MainBundle\Entity\Product p WHERE p.id = :picture_id AND q.product = p.id SQL; $query = $this->_em->createQuery($dql)->setParameter('picture_id', $id); return $query->setMaxResults(1)->getResult(); } }
Чтобы использовать это из контроллера
$em = $this->getDoctrine()->getManager(); $product = $em->getRepository('ShopiousMainBundle:Product')->findProductWithPicture($id); return $this->render('ShopiousMainBundle:Product:show.html.twig', array( 'product' => $product[0] ));
В созданном шаблоне Twig вы можете получить к ним доступ так
<p>{{ product.id }} <p>{{ product.name }} <p>{{ product.picture.whatever_property }}