2012-07-03 42 views
7

La documentación es muy pobre cuando se trata de explicar la creación de relaciones entre entidades. Entonces, tendré que pedir ayuda a mis compañeros StackExchangers. Por lo tanto, yo estoy tratando de construir los siguientes casos:¿Cómo ManyToMany y OneToMany en Symfony y Doctrine?

Caso 1

Un User pertenece a una o más Group, y una Group puede tener muchas Permission. Un User también puede tener un Permission.

Caso 2

Un Ticket tiene un Category, múltiples TagComment y múltiple.

¡Gracias de antemano!

Respuesta

17

Cosa segura. Lo primero que debemos entender es que no hay una "forma única" de hacerlo. Doctrine brinda mucha flexibilidad en términos de cómo define the relationship - incluso si las definiciones múltiples producen el mismo DDL exacto (y esto es importante de entender) algunas de las elecciones de mapeo solo afectan al lado del objeto del ORM, no al lado del modelo)

Aquí está tu Usuarios/Grupos/ejemplo de permisos, que son en realidad todo muchos-a-muchos asociaciones (excluí todo no relevante, pero se requiere código, como PK definición de columna)

<?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 {} 

Si usted tiene preguntas sobre lo que está pasando aquí, házmelo saber.

Ahora, a su segundo ejemplo

<?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 {} 

Al igual que antes, que me haga saber si desea que nada de esto se explica.

P.S. Nada de esto fue realmente probado, simplemente lo apagué en mi IDE muy rápido. Puede haber un error tipográfico o dos;)

+0

¿Por qué InverseJoinColumns? – vinnylinux

+0

Además, ¿por qué diferentes nombres de tabla?Y should'nt permiso_id ser declarado? – vinnylinux

+1

@vinnylinux - No recibo sus preguntas por completo. InverseJoinColumns es la forma en que declaras una relación unidireccional de muchos a muchos: no hay un "por qué" para responder, así es como se hace. Y no entiendo de qué se trata en realidad tu segunda pregunta. –

4

Prueba esto:

Class User { 
/** 
    * @ORM\OneToMany(targetEntity="path\to\group", mappedBy="user", cascade={"persist", "remove"}) 
    */ 
    private $group; 

Usted tendrá uno a muchos relación entre User y Group .. El targetEntity es el camino a la entidad que desea tener una relación con, el mappedBy es la variable de la Group Entidad. cascade significa User puede añadir a Group y retirar del Group

Grupo Clase {

/** 
* @ORM\ManyToOne(targetEntity="path\to\user, inversedBy="group") 
* @ORM\JoinColumn(name="user_id", referencedColumnName="id") 
*/ 
private $user; 

Este es el lado de la reserva de la relación .. targetEntity deberían tener el camino de regreso a la entidad matriz, que es User en este caso. inversedBy es la variable de la entidad User. JoinColumn le está diciendo a Doctrine a qué unirse, esto se hace automáticamente si no lo configura usted mismo.

+0

¿Puedes explicarlo? – MDrollette

Cuestiones relacionadas