Как ManyToMany и OneToMany в Symfony и Doctrine?
Я нахожу документацию очень плохой, когда дело доходит до объяснения создания отношений между сущностями. Так что мне придется обратиться за помощью к моим коллегам StackExchangers. Итак, я пытаюсь построить следующие случаи:
корпус 1
A User
принадлежит одному или нескольким Group
и Group
может быть много Permission
. А User
также может иметь Permission
.
корпус 2
A Ticket
есть Category
, несколько Tag
и несколько Comment
.
спасибо заранее!
2 ответов
конечно. Первое, что нужно понять, - это то, что нет "одного способа" сделать это. Доктрина дает много гибкости с точки зрения того, как вы определить отношение - даже если несколько определений производят один и тот же DDL (и это важно понять - некоторые из вариантов отображения влияют только на объектную сторону ORM, а не на модельную сторону)
вот пример ваших пользователей / групп / разрешений, которые на самом деле являются ассоциациями "многие ко многим" (я исключил все несущественный, но необходимый код, например определение столбца PK)
<?php
namespace Your\Bundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity
*/
class User
{
/**
* Many-To-Many, Unidirectional
*
* @var ArrayCollection $groups
*
* @ORM\ManyToMany(targetEntity="Group")
* @ORM\JoinTable(name="user_has_group",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")}
* )
*/
protected $groups;
/**
* Many-To-Many, Unidirectional
*
* @var ArrayCollection $permissions
*
* @ORM\ManyToMany(targetEntity="Permission")
* @ORM\JoinTable(name="user_has_permission",
* joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="permission_id", referencedColumnName="id")}
* )
*/
protected $permissions;
public function __construct()
{
$this->groups = new ArrayCollection();
$this->permissions = new ArrayCollection();
}
}
/**
* @ORM\Entity
*/
class Group
{
/**
* Many-To-Many, Unidirectional
*
* @var ArrayCollection $permissions
*
* @ORM\ManyToMany(targetEntity="Permission")
* @ORM\JoinTable(name="group_has_permission",
* joinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="permission_id", referencedColumnName="id")}
* )
*/
protected $permissions;
public function __construct()
{
$this->permissions = new ArrayCollection();
}
}
/**
* @ORM\Entity
*/
class Permission {}
Если у вас есть вопросы о том, что происходит здесь, дайте мне знать.
теперь, ко второму примеру
<?php
namespace Your\Bundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity
*/
class Ticket
{
/**
* Many-To-One, Unidirectional
*
* @var Category
*
* @ORM\ManyToOne(targetEntity="Category")
* @ORM\JoinColumn(name="category_id", referencedColumnName="id")
*/
protected $category;
/**
* Many-To-Many, Unidirectional
*
* @var ArrayCollection $permissions
*
* @ORM\ManyToMany(targetEntity="Tag")
* @ORM\JoinTable(name="tickt_has_tag",
* joinColumns={@ORM\JoinColumn(name="ticket_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="id")}
* )
*/
protected $tags;
/**
* One-To-Many, Bidirectional
*
* @var ArrayCollection $comments
*
* @ORM\OneToMany(targetEntity="Comment", mappedBy="ticket")
*/
protected $comments;
public function __construct()
{
$this->tags = new ArrayCollection();
$this->comments = new ArrayCollection();
}
}
/**
* @ORM\Entity
*/
class Comment
{
/**
* Many-To-One, Bidirectional
*
* @var Ticket $ticket
*
* @ORM\ManyToOne(targetEntity="Ticket")
* @ORM\JoinColumn(name="ticket_id", referencedColumnName="id")
*/
protected $ticket=null;
}
/**
* @ORM\Entity
*/
class Tag {}
/**
* @ORM\Entity
*/
class Category {}
Как и раньше, дайте мне знать, если вы хотели, чтобы все это объяснить.
P.S. На самом деле ничего из этого не было протестировано, я просто быстро ударил его в своей IDE. Может быть опечатка или две ;)
попробуйте это:
Class User {
/**
* @ORM\OneToMany(targetEntity="path\to\group", mappedBy="user", cascade={"persist", "remove"})
*/
private $group;
у вас будет одно ко многим отношениям между User
и Group
.. The targetEntity
- это путь к сущности, которую вы хотите иметь отношения с mappedBy
является переменной из Group
сущности. cascade
означает User
добавить в Group
и удалить из Group
Группа Класс {
/**
* @ORM\ManyToOne(targetEntity="path\to\user, inversedBy="group")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
это резервная сторона отношений.. targetEntity
должен иметь путь обратно к родительской сущности, которая User
в этом случае. inversedBy
является переменной из User
сущности. JoinColumn
просто говорит доктрине, что присоединиться, это автоматически делается, если вы не установите его самостоятельно.