2015-11-23 7 views
0

Я пытаюсь найти подходящую модель для отношений между Группой пользователей, короткое отображаемое сообщение оповещения и названное местоположение.Связь базы данных Symfony2/Doctrine2 между группой, сообщением и местоположением

Например: студенты и интерны (Групп), возможно, потребуется специальное указание (Message), который будет отображаться в верхней части страницы (Места), в то время как преподавателям и Teammanagers, возможно, потребуются, чтобы увидеть другие строка текста.

  • Место может иметь несколько сообщений, но только по одному для каждой группы.
  • Группа может иметь несколько сообщений, но только по одному для каждого места.
  • Многим группам (в тысячах, в некоторых случаях) может быть назначено одно и то же идентичное сообщение, поэтому сообщение как объект с ключами к местоположению группы & вызовет много дублирования.
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; 
} 

Я чувствую, что там должна быть много-к-одному отношения между сообщениями и местоположением, и отношением многих к одному между группами и некоторыми комбинациями «Message + Location» сущностью.

У меня возникли проблемы с созданием сущностей таким образом.

ответ

1

С вашей схеме, вы можете сделать что-то подобное:

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!' 
        ); 
      */ 
     } 
    } 
} 
+0

Круто! Я склонялся к объединению «Местоположение» и «Сообщение» вместе с сущностью «LocationMessage» («Много-к-одному» для местоположения, «Множество ко многим для групп», «Один-к-одному» для сообщений). Но я думаю, что я мог бы просто использовать объект Message! – Fx32

+0

Я думаю, что это лучший способ, потому что у вас есть все, что вам нужно, в сообщениях (Location + Groups), и это может произойти только в том случае, если вы добавляете сообщение (или редактируете). Попробуйте это. Совет. Вы можете связать цепочку $ this-> getGroups() [...] $ group-> getMessages() ', чтобы проверить, уникально ли это местоположение или нет. –

+0

Как проверить, подтверждение не выполняется? Я просто положил $ group-> addMessage ($ location); в блоке try-catch? – Fx32

Смежные вопросы