Запрос соединения Symfony с отношением «Один ко многим»

#symfony #dql

Вопрос:

Я совершенно новичок в symfony, как и в DQL. У меня проблема с запросом, а именно, я хочу сравнить идентификаторы между «term_id» из таблицы «TermAssign» с «идентификатором» из таблицы «Термин», а затем те, кто соответствует, должны отображаться в шаблоне. Связь между термином и термином является одной из многих. Существует также табличное предложение, которое имеет отношение к одному объекту с табличным термином.

Это моя Term.php:

    <?php

    namespace AppOfferBundleEntity;
    use AppOfferBundleRepositoryTermRepository;
    use DoctrineCommonCollectionsArrayCollection;
    use DoctrineCommonCollectionsCollection;  
    use DoctrineORMMapping as ORM;

/**
 * @ORMEntity(repositoryClass=TermRepository::class)
 * @ORMTable(name="term")
 */
class Term
{
    /**
     * @ORMId
     * @ORMGeneratedValue
     * @ORMColumn(type="integer")
     */
    private $id;

    /**
     * @ORMColumn(type="string", length=255, nullable=true, name="term_description")
     */
    private $term_description;

    /**
     * @ORMOneToMany(targetEntity=TermAssign::class, mappedBy="term")
     */
    private $assign;

    public function __construct()
    {
        $this->assign = new ArrayCollection();
    }

  function getId(): ?int
    {
        return $this->id;
    }

    public function getTermDescription(): ?string
    {
        return $this->term_description;
    }

    public function setTermDescription(?string $term_description): self
    {
        $this->term_description = $term_description;

        return $this;
    }

    /**
     * @return Collection|TermAssign[]
     */
    public function getAssign(): Collection
    {
        return $this->assign;
    }

    public function addAssign(TermAssign $assign): self
    {
        if (!$this->assign->contains($assign)) {
            $this->assign[] = $assign;
            $assign->setTerm($this);
        }

        return $this;
    }

    public function removeAssign(TermAssign $assign): self
    {
        if ($this->assign->removeElement($assign)) {
            // set the owning side to null (unless already changed)
            if ($assign->getTerm() === $this) {
                $assign->setTerm(null);
            }
        }

        return $this;
    }
}
 

Это Offer.php:

 <?php

namespace AppOfferBundleEntity;

use AppOfferBundleRepositoryOfferRepository;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use DoctrineORMMapping as ORM;
use SymfonyComponentValidatorConstraintsDateTime;

/**
 * @ORMEntity(repositoryClass=OfferRepository::class)
 */
class Offer
{
    /**
     * @ORMId
     * @ORMGeneratedValue
     * @ORMColumn(type="integer")
     */
    private $id;

    /**
     * @ORMColumn(type="string")
     */
    private $title;

    /**
     * @ORMColumn(type="date", name="offer_date")
     */
    private $date;

    /**
     * @ORMColumn(type="string", unique=true)
     */
    private $number;

    /**
     * @ORMColumn(type="string")
     */
    private $description;

    /**
     * @ORMOneToMany(targetEntity=TermAssign::class, mappedBy="offer")
     */
    private $terms;

    public function __construct()
    {
        $this->terms = new ArrayCollection();
    }

    /**
     * Getting offer's id
     */
    public function getId(): ?int
    {
        return $this->id;
    }

    /**
     * getting offer's Title
     */
    public function getTitle(): string
    {
        return $this->title;
    }

    /**
     * Setting offer's name
     */
    public function setTitle($title): self
    {
        $this->title = $title;

        return $this;
    }

    /**
     * getting offer's date
     */
    public function getDate(): ?DateTime
    {
        return $this->date;
    }

    /**
     * Setting offer's date
     */
    public function setDate($date): self
    {
        $this->date = $date;

        return $this;
    }

    /**
     * Offer's number
     */
    public function getNumber() : string
    {
        return $this->number;
    }

    /**
     * Setting offer's number
     */
    public function setNumber($number): self
    {
        $this->number = $number;

        return $this;
    }

    /**
     * Offer's description
     */
    public function getDescription()
    {
        return $this->description;
    }

    /**
     * Setting offer's description
     */
    public function setDescription($description): void
    {
        $this->description = $description;
    }

    /**
     * @return Collection|TermAssign[]
     */
    public function getTerms(): Collection
    {
        return $this->terms;
    }

    public function addTerm(TermAssign $term): self
    {
        if (!$this->terms->contains($term)) {
            $this->terms[] = $term;
            $term->setOffer($this);
        }

        return $this;
    }

    public function removeTerm(TermAssign $term): self
    {
        if ($this->terms->removeElement($term)) {
            // set the owning side to null (unless already changed)
            if ($term->getOffer() === $this) {
                $term->setOffer(null);
            }
        }

        return $this;
    }
}
 

And this is TermAssign.php:

 <?php

namespace AppOfferBundleEntity;

use AppOfferBundleRepositoryTermAssignRepository;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use DoctrineORMMapping as ORM;

/**
 * @ORMEntity(repositoryClass=TermAssignRepository::class)
 */
class TermAssign
{
    /**
     * @ORMId
     * @ORMGeneratedValue
     * @ORMColumn(type="integer")
     */
    private $id;

    /**
     * @ORMManyToOne(targetEntity=Offer::class, inversedBy="terms")
     */
    private $offer;

    /**
     * @ORMManyToOne(targetEntity=Term::class, inversedBy="assign")
     */
    private $term;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getOffer(): ?Offer
    {
        return $this->offer;
    }

    public function setOffer(?Offer $offer): self
    {
        $this->offer = $offer;

        return $this;
    }

    public function getTerm(): ?Term
    {
        return $this->term;
    }

    public function setTerm(?Term $term): self
    {
        $this->term = $term;

        return $this;
    }


}
 

Я действительно пришел с запросом такого рода:

  /**
 * @return Term[] Returns an array of Term objects
 */
public function findByIdField():array
{
    $em = $this->getEntityManager();
    $query = $em->createQuery("SELECT t, a FROM AppOfferBundleEntityTerm t JOIN t.term a WHERE a.term_id = t.id");
    return $query->getResult();
}
 

Но это бесполезно.

Кроме того, это часть моего контроллера, где я вызываю запрос для передачи в шаблон:

OfferController.php

 /**
 * @Route("/{id}", name="offer_show", methods={"GET"})
 */
public function show(Offer $offer, int $id): Response
{
    $termAssigns = $this->getDoctrine()
        ->getRepository(TermAssign::class)
        ->findBy(
            ['offer'=>$id]
        );
    $terms = $this->getDoctrine()
        ->getRepository(Term::class)
        ->findByIdField();
    $conditions = $this->getDoctrine()
        ->getRepository(Condition::class)
        ->findAll();

    return $this->render('offer/show.html.twig', [
        'offer' => $offer,
        'terms'=> $terms,
        'conditions'=>$conditions,
        'termAssigns'=>$termAssigns,
    ]);
}
 

Вопрос в том, что я могу сделать, чтобы достичь чего-то подобного

ВЫБЕРИТЕ описание ИЗ Условия.t, где ‘t.id’=’ta.term_id’

«та» — это таблица обозначений терминов.

Ответ №1:

Это было гораздо проще, чем я себе представлял… Мне не нужно было создавать новый запрос, все, что мне нужно было сделать, это импортировать репозиторий TermAssign для отображения функции (), расположенной в OfferController.php и используйте функцию findBy() для извлечения терминов из таблицы терминов. Решение ниже:

OfferController.php:

 /**
     * @Route("/{id}", name="offer_show", methods={"GET"})
     */
    public function show(Offer $offer, int $id, TermAssign $terms): Response
    {
        **$termAssigns = $this->getDoctrine()
            ->getRepository(TermAssign::class)
            ->findBy(
                ['offer'=>$id]
            );

        $terms = $this->getDoctrine()
            ->getRepository(Term::class)
            ->findBy(
                ['id'=>$terms->getId()]
            );**

        $conditions = $this->getDoctrine()
            ->getRepository(Condition::class)
            ->findAll();

        return $this->render('offer/show.html.twig', [
            'offer' => $offer,
            'terms'=> $terms,
            'conditions'=>$conditions,
            'termAssigns'=>$termAssigns,
        ]);
    }