I'm trying to come up with the right model for the relationship between a Group of users, a short displayed alert Message, and a named Location.
For example: Students and Interns ( Groups ) might need a special instruction ( Message ) to be displayed at the top of a page ( Location ), while Teachers and Teammanagers might need to see a different string of text.
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;
}
I feel like there should be a Many-to-one relation between Messages and a Location, and a Many-to-one relation between groups and some combined "Message+Location" entity.
I'm having trouble setting up entities in this way though.
With your schema, you can do something like that :
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;
}
To ensure the [1] condition, you can make a callback in your Message
entity. This callback will check, when you're inserting a Message that a group doesn't have an another message at the same location.
To do a callback, here the doc is :
/**
* @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!'
);
*/
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.