Я пытаюсь найти правильную модель отношений между группой пользователей, коротким отображаемым предупреждающим сообщением и именованным местоположением.
Например: студенты и стажеры (группы) может понадобиться специальная инструкция (Сообщение) для отображения в верхней части страницы (Место нахождения), в то время как учителям и руководителям команд может понадобиться увидеть другую строку текста.
class Message {
/**
* @ORM\ManyToOne(targetEntity="...Bundle\Entity\Group", inversedBy="messages")
* @ORM\JoinColumn(name="group_id", referencedColumnName="id", nullable=false)
*/
protected $groups;
/**
* @ORM\ManyToOne(targetEntity="...Bundle\Entity\Location", inversedBy="messages")
* @ORM\JoinColumn(name="location_id", referencedColumnName="id", nullable=false)
*/
protected $location;
}
Я чувствую, что должно быть отношение «многие к одному» между сообщениями и местоположением, и отношение «многие к одному» между группами и какой-либо объединенной сущностью «сообщение + местоположение».
У меня проблемы с настройкой сущностей таким способом.
С вашей схемой вы можете сделать что-то вроде этого:
class Message {
/**
* @ORM\ManyToMany(targetEntity="...Bundle\Entity\Group", inversedBy="messages")
* @ORM\JoinColumn(name="group_message"* joinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="message_id", referencedColumnName="id")})
*/
protected $groups; //Here, a group can have many messages and a messages can be attached at many groups so => manyToMany
/**
* @ORM\ManyToOne(targetEntity="...Bundle\Entity\Location", inversedBy="messages")
* @ORM\JoinColumn(name="location_id", referencedColumnName="id", nullable=false)
*/
protected $location; //[1] Message can have One location and location can have many messages in the case of messages at the same location are not assigned at the same group.
}
class Location {
/**
* @ORM\OneToMany(targetEntity="...Bundle\Entity\Message", mappedBy="location")
* @ORM\JoinColumn(name="message_id", referencedColumnName="id", nullable=false)
*/
protected $messages;
}
class Group {
/**
* @ORM\ManyToMany(targetEntity="...Bundle\Entity\Message", mappedBy="groups")
*/
protected $messages;
}
Чтобы обеспечить условие [1], вы можете сделать обратный вызов в вашем Message
юридическое лицо. Этот обратный вызов будет проверять, когда вы вставляете сообщение, что у группы нет другого сообщения в том же месте.
Чтобы сделать обратный звонок, здесь документ:
/**
* @Assert\Callback({"Vendor\Package\Validator", "validate"})
*/
class Message {
[...]
public function validate(ExecutionContextInterface $context)
{
// check if the location is already used for one of the group on $this (entity returned by the form)
foreach($this->getGroups() as $group) {
foreach($group->getMessages as $message) {
if ($this->getLocation() == $message->getLocation()) {
$context->buildViolation('Location already used!')
->atPath('location')
->addViolation();
}
}
}
// If you're using the old 2.4 validation API
/*
$context->addViolationAt(
'location',
'Location already used!'
);
*/
}
}
}
Других решений пока нет …