@sadCake

Как заставить доктрину увидеть поля в jointable?

Есть 2 сущности. City и Service.
В Service:
/**
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\City", inversedBy="services")
     * @ORM\JoinTable(
     *     name="city_service_rel",
     *     joinColumns={@ORM\JoinColumn(name="service_id", referencedColumnName="id", onDelete="CASCADE")},
     *     inverseJoinColumns={@ORM\JoinColumn(name="city_id", referencedColumnName="id", onDelete="CASCADE")}
     * )
     */
    protected $cities;

В City:

/**
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\City", mappedBy="cities")
     */
    protected $services;


Пытаюсь через query builder написать запрос, чтобы получить все сервисы, которые есть в определенном городе.

$qb = $this->createQueryBuilder('service');

        $qb
            ->where('service.active = true')
            ->andWhere($qb->expr()->isNotNull('service.representative'))
            ->innerJoin(
                'service.cities',
                'cities',
                'WITH',
                'cities.city_id = :id'
            )
            ->setParameter('id', $cityId)
        ;


В итоге доктрина не может найти связанные колонки, а если заджойнить service.cities, то он пытается найти какие-то свойства в классе City.
  • Вопрос задан
  • 57 просмотров
Решения вопроса 1
passionkillah
@passionkillah
Backend-разработчик
У вас маппинги уже настроены таким образом, что вы можете просто достать нужный город и через геттер получить коллекцию сервисов, которые в нем есть - доктрина все сделает за вас.

Что касается запроса, он не совсем корректен. Во-первых, вы подставляете параметр не туда, куда необходимо: последний параметр в innerJoin'е отвечает за то, по какому параметру соединять две сущности. Во-вторых, вы обращаетесь к city_id при том, что делаете запрос не на SQL, а на DQL - то есть по сути во время выполнения этого запроса вы присоединяете не таблицу, а коллекцию объектов. На этом уровне доктрина не в курсе ни о каком city_id. В-третьих, доктрина при присоединении коллекции понимает, что речь идет о many-to-many - соответственно, последние два параметра при join'е можно опустить:
->join('service.cities', 'city')
->andWhere('city.id = :id')
->setParameter('id', $id)

Работая с доктриной, следует немного поменять мышление: стоит абстрагироваться от бд и думать о сущностях как об обычных объектах. Надеюсь, что мне удалось корректно сформулировать ответ.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
YCLIENTS Москва
от 200 000 до 350 000 ₽
Ведисофт Екатеринбург
от 25 000 ₽
ИТЦ Аусферр Магнитогорск
от 100 000 до 160 000 ₽