Doctine : OneToMany + ManyToOne = ManyToMany

Пример реализации и выборки данных:

Новость:

<?php

namespace App\Entity;

use App\Repository\NewsRepository;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;

#[ORM\Entity(repositoryClass: NewsRepository::class)]
class News extends AbstractDocument
{
    #[ORM\OneToMany(targetEntity: NewsTheme::class, mappedBy: 'news', orphanRemoval: true)]
    private Collection $themes;

    public function __construct()
    {
        parent::__construct();
        $this->themes = new ArrayCollection();
    }
}

Тема:

<?php

namespace App\Entity;

use App\Repository\ThemeRepository;
use App\Service\Attribution\PropertyAttribute\PropertyDescription;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: ThemeRepository::class)]
class Theme extends AbstractDocument
{
    /**
     * @var Collection<int, NewsTheme>
     */
    #[ORM\OneToMany(targetEntity: NewsTheme::class, mappedBy: 'theme', orphanRemoval: true)]
    private Collection $news;

    public function __construct()
    {
        parent::__construct();
        $this->news = new ArrayCollection();
    }

    public function getNews(): Collection
    {
        return $this->news;
    }

    public function setNews(Collection $value): static
    {
        $this->news = $value;
        return $this;
    }
}

Связь:

<?php

namespace App\Entity;

use App\EntityData\EntityInterface;
use App\EntityData\EntityTrait;
use App\Repository\NewsThemeRepository;
use App\Repository\ThemeRepository;
use Carbon\CarbonImmutable;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: NewsThemeRepository::class)]
#[ORM\UniqueConstraint(name: "NewsThemeUk", columns: ['theme_id','news_id',])]
class NewsTheme implements EntityInterface
{
    use EntityTrait;

    #[ORM\ManyToOne(cascade: ['persist', 'remove'], inversedBy: 'themes')]
    #[ORM\JoinColumn(nullable: false, onDelete: 'RESTRICT')]
    private News $news;

    #[ORM\ManyToOne(cascade: ['persist', 'remove'], inversedBy: 'news')]
    #[ORM\JoinColumn(nullable: false, onDelete: 'RESTRICT')]
    private Theme $theme;

    public function getNews(): News
    {
        return $this->news;
    }

    public function setNews(News $news): static
    {
        $this->news = $news;

        return $this;
    }

    public function getTheme(): Theme
    {
        return $this->theme;
    }

    public function setTheme(Theme $theme): static
    {
        $this->theme = $theme;

        return $this;
    }
}

Чтобы выбрать данные минуя сложные джойны напишем запрос:

class NewsRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, News::class);
    }

    public function getAllNewsByTheme(Theme $theme): array
    {
        return $this->createQueryBuilder('t')
            ->select('t')
            ->innerJoin('t.themes', 'themes')
            ->where("themes.theme = :themeId")->setParameter('themeId', $theme)
            ->getQuery()
            ->getResult();
    }
}

Вот так выбираем все новости определенной темы:

$allNews = $newsRepository->getAllNewsByTheme($theme);

Удачки.


11.09.2021 07:08

Комментарии

СПАСИБО. ВЫ ЛУЧШИЕ. Позже еще чего нибудь придумаю.
etk |

Copyrights © 2007 - 2026 YaPro.Ru