Symfony2/Doctrine2群组、消息和位置之间的数据库关系

Symfony2/Doctrine2 database relationship between a group, a message and a location

我正在尝试为一组用户、显示的简短警报消息和命名位置之间的关系提出正确的模型。

例如:学生和实习生 (Groups) 可能需要特殊说明 (Message)页面(位置),而教师和团队经理可能需要查看不同的文本字符串。

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;
}

我觉得 Messages 和 Location 之间应该有多对一的关系,组和一些组合的 "Message+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实体中进行回调。当您插入消息时,此回调将检查群组在同一位置没有另一条消息。

要进行回调,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!'
                    );
            */
        }
    }
}