Доктрина: вручную прикрепить связанную коллекцию - PullRequest
0 голосов
/ 15 февраля 2019

Бэкэнд-приложение My Doctrine имеет типы сущностей Lead и Contact.Один Lead может иметь много Contact с.Моя проблема в том, что я хочу сохранить контакты в свойстве $contacts ведущего объекта, но когда я получаю запрос, у меня уже есть связанные контакты, потому что они мне уже были нужны ранее в другом контексте.Поэтому я хочу прикрепить уже извлеченные контакты к вновь извлеченному ведущему объекту вручную.

Вот проблема в деталях:

Запрос на выборку ведущих контактов должен учитывать некоторые важные моменты, например::

  • Они должны быть актуальны для текущего пользователя (существует другая ассоциация с User)
  • Он не должен содержать disabled записей

Таким образом, существует соответствующая функция getContactsByLead(), которая вызывается веб-интерфейсом через веб-сервис:

$qb = $repo->createQueryBuilder('c');
$qb->where($qb->expr()->eq('c.lead', '?0'));
$qb->setParameter(0, $leadId);
$qb->andWhere('c.disabled = 0');
$qb->andWhere($qb->expr()->eq('c.user', '?1'));
$qb->setParameter(1, $this->getUser()->getId()); 
return $qb->getQuery()->execute();

В настоящее время существует другая функция getLeadWithContacts(), которая вместо этих контактов должна предоставлять объект Lead.хранится в его contacts свойстве:

/**
 * @ORM\OneToMany(targetEntity="AppBundle\Entity\LeadContact", mappedBy="lead")
 */
protected $contacts;

Так что эта функция getLeadWithContacts() содержит запрос, очень похожий на getContactsByLead(), но вместо этого выбирает лидерство и LEFT JOIN связывает контакты сте же условия:

$qb = $this->createQueryBuilder('l');
$qb->leftJoin('l.contacts', 'c', Expr\Join::WITH, 'c.disabled = 0');
$qb->addSelect('c');
$qb->where($qb->expr()->eq('l.id', $leadId));
$qb->andWhere($qb->expr()->eq('c.user', '?0'));
$qb->setParameter(0, $this->getUser()->getId()); 
return $qb->getQuery()->getOneOrNullResult();

Это проблематично, поскольку разработчик должен всегда следить за тем, чтобы обе функции одинаково соблюдали условия.Это уже приводило к большим проблемам, когда разработчик забыл настроить один из запросов при изменении условий.

Вот почему я хочу заменить getLeadWithContacts() на что-то вроде этого:

public function getLeadWithContacts($leadId) {
    $lead = $this->getLead($leadId);
    $contacts = $this->getContactsByLead($lead);
    $lead->setContacts($contacts);
    return $lead;
}

Но доктрина не предоставляет метод установки для всей коллекции.И в этот момент мне также интересно, если это работает, если я реализую это самостоятельно.Или это приведет к побочным эффектам, особенно когда я снова сохраню этот ведущий объект в базе данных?Я боюсь получить побочные эффекты, такие как дубликаты контактов и замечать их, когда уже слишком поздно.Вот почему я спрашиваю здесь ...

...