Doctrine — множество объектов с таблицей в качестве цели

#php #postgresql #symfony #doctrine-orm #annotations

#php #postgresql #symfony #doctrine-orm #аннотации

Вопрос:

Возможно ли в Doctrine создать однонаправленную связь ManyToMany с таблицей в качестве targetEntity?

У меня есть следующее созвездие базы данных: задание и таблица сервисов, которые подключены через Doctrine ManyToMany (объединенная таблица называется service2job), потому что задание может иметь несколько сервисов, и одни и те же сервисы могут появляться в разных заданиях. Теперь есть таблица employee. Сотрудник может выполнять некоторые услуги, которые зависят от задания.

И вот что сложнее: один или несколько сотрудников могут работать в одной службе в зависимости от задания. Итак, мне нужна другая таблица соединений, которая соединяет service2job и employee (emp2ser2job), которые должны быть сгенерированы Doctrine.

Сторона Doctrine / Symfony: Сервисы задания сохраняются как ArrayCollection в классе Job. Службы и задания подключаются через Doctrine ManyToMany (аннотацию).

Я хочу сохранить сервисы, в зависимости от задания, выполняемого сотрудником, в классе Employee. Но вот проблема: для этого мне нужно сослаться на отношение ManyToMany в Employee к таблице service2job , потому что я не хочу создавать класс Service2Job, на который мне просто нужно ссылаться.

Есть ли какая-либо возможность сделать это без создания класса (Emp2Ser2Job) только для сопоставления и как объекта для ссылки?

Код:

 // Service
class Service 
{
  private $id;
}

// Job
...
use DoctrineORMMapping as ORM;
...

class Job 
{
   public function __construct() 
   {
     $this->services = new ArrayCollection();
   }
   /**
   * @ORMManyToMany(targetEntity="KuMiVServicesBundleEntityService")
     // table that should be targetEntity in Employee ($services);
   * @ORMJoinTable(name="service2job",
   *      joinColumns={@ORMJoinColumn(name="job_id", referencedColumnName="id")},
   *      inverseJoinColumns={@ORMJoinColumn(name="service_id",  referencedColumnName="id")}
   *      )
   **/
   private $services;
   ...
}

// Employee
class Employee 
{
   public function __construct() 
   {
     $this->services = new ArrayCollection();
   }

   /**
   * @ORMManyToMany //how should annotation be here to make a ManyToMany unidirectional to the table service2job?
   * @ORMJoinTable(name="employee2service2job",
   *      joinColumns={@ORMJoinColumn(name="employee_id", referencedColumnName="id")},
   *      inverseJoinColumns={@ORMJoinColumn(name="job_id", referencedColumnName="job_id"), @ORMJoinColumn(name="service_id", referencedColumnName="service_id")}
   *      )
   **/
   private $services;
}
  

Комментарии:

1. Я бы просто создал что-то вроде JobApplication класса, который соединяет employee, задание и сервис … вероятно, рано или поздно вы захотите добавить туда больше информации … возможности включают такие вещи, как created_at , confirmed_at , confirmed_by

2. Это то, чего я не хотел, но кажется единственной возможностью…

3. Я думаю, что ваша Service2Job таблица на самом деле должна представлять собой трехходовую табличную связь (с уникальным / первичным ключом на user_id , job_id и service_id и индексом на job_id и service_id )

4. @Talus — Возможно, что 2 сотрудника выполняют одну и ту же услугу (например, если они работают вместе), поэтому ограничение уникальности не является хорошей идеей.

5. Отсюда уникальный / первичный ключ для трех полей: сотрудник не может быть в службе / задании более одного раза, верно? Если это 2 сотрудника, то ключ соблюдается. Если вы хотите получить всех сотрудников для задания и службы, вы можете выполнить basic SELECT employee FROM services2jobs WHERE service_id = ? AND job_id = ? , отсюда и индекс по этим двум полям.

Ответ №1:

Когда у отношения есть другие ссылки / атрибуты, это больше не отношение, почему? потому что, если для отношения требуется больше ссылок / атрибутов, тогда его следует обрабатывать как модель. В вашем случае вам следует следовать совету @Talu.

 Service
 - jobs

Jobs
 - services

Service2Job
 - jobs
 - services
 - employees //this converts your relationship in model

Employees
 - services2jobs
  

Комментарии:

1. Я оставил свою модель базы данных такой, какой она была, и последовал совету @nifr и создал дополнительный объект для сопоставления атрибута service2job, но ваше заявление о том, что это больше не связь, открыло мне разум.