Задать вопрос
@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.
  • Вопрос задан
  • 67 просмотров
Подписаться 2 Простой Комментировать
Помогут разобраться в теме Все курсы
  • Skillbox
    Веб-разработчик на PHP
    9 месяцев
    Далее
  • Хекслет
    PHP-разработчик
    10 месяцев
    Далее
  • Нетология
    Веб-разработчик с нуля: профессия с выбором специализации
    14 месяцев
    Далее
Решения вопроса 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)

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

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

Похожие вопросы
FoodSoul Калининград
от 180 000 до 250 000 ₽
IT-Spirit Москва
от 230 000 до 320 000 ₽
IT ATLAS Москва
от 250 000 до 500 000 ₽