#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, но ваше заявление о том, что это больше не связь, открыло мне разум.