Symfony2 desde 0: Relaciones en Doctrine

Hemos generado las entidades automáticamente y también hemos indicado que la definición de estas estará en archivos yml. Ahora vamos a ver las relaciones en Doctrine que utilizaremos para el blog.

Src/Web/BlogBundle/Resources/config/doctrine/Posts.orm.yml aquí tenemos la definición de cada campo y de las relaciones.

Web\BlogBundle\Entity\Posts:
    type: entity
    table: posts
    indexes:
        fk_category_post:
            columns:
                - category_id
        fk_user_post:
            columns:
                - user_id
    id:
        id:
            type: bigint
            nullable: false
            unsigned: false
            id: true
            generator:
                strategy: IDENTITY
    fields:
        title:
            type: string
            nullable: true
            length: 255
            fixed: false
        description:
            type: string
            nullable: true
            length: 255
            fixed: false
        image:
            type: string
            nullable: true
            length: 255
            fixed: false
        content:
            type: string
            nullable: true
            length: 255
            fixed: false
        status:
            type: string
            nullable: true
            length: 50
            fixed: false
        date:
            type: date
            nullable: true
        time:
            type: time
            nullable: true

    manyToOne:
        #Relación de muchos a uno, muchos posts para una categoria
        category:
            targetEntity: Categories
            cascade: {  }
            mappedBy: null
            inversedBy: posts
            joinColumns:
                category_id:
                    referencedColumnName: id
            orphanRemoval: false

        #Relación de muchos a uno, muchos posts de un usuario
        user:
            targetEntity: Users
            cascade: {  }
            mappedBy: null
            inversedBy: posts
            joinColumns:
                user_id:
                    referencedColumnName: id
            orphanRemoval: false

#Añadimos la relación oneToMany 
    oneToMany:
        #Relación de uno a muchos, un post puede tener muchas tags
        tagsPosts:
            targetEntity: TagsPosts
            mappedBy: post
            cascade: ["persist"]
    lifecycleCallbacks: {  }

En el yml de TagsPosts:

Web\BlogBundle\Entity\TagsPosts:
    type: entity
    table: tags_posts
    indexes:
        fk_tag_id_tp:
            columns:
                - tag_id
        fk_post_id_tp:
            columns:
                - post_id
    id:
        id:
            type: bigint
            nullable: false
            unsigned: false
            id: true
            generator:
                strategy: IDENTITY
    manyToOne:
        tag:
            targetEntity: Tags
            cascade: {  }
            mappedBy: null
            inversedBy: null
            joinColumns:
                tag_id:
                    referencedColumnName: id
            orphanRemoval: false
        post:
            targetEntity: Posts
            cascade: {  }
            mappedBy: null
#Tenemos que añadir el inversedBy
            inversedBy: tagsPosts 
            joinColumns:
                post_id:
                    referencedColumnName: id
            orphanRemoval: false
    lifecycleCallbacks: {  }

Ahora modificaremos la entidad src/Web/BlogBundle/Entity/Posts.php, le añadiremos métodos para la relación OneToMany.

<?php

namespace Web\BlogBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * Posts
 */
class Posts {

    /**
     * @var integer
     */
    private $id;

    /**
     * @var string
     */
    private $title;

    /**
     * @var string
     */
    private $description;

    /**
     * @var string
     */
    private $image;

    /**
     * @var string
     */
    private $content;

    /**
     * @var string
     */
    private $status;

    /**
     * @var \DateTime
     */
    private $date;

    /**
     * @var \DateTime
     */
    private $time;

    /**
     * @var \Web\BlogBundle\Entity\Categories
     */
    private $category;

    /**
     * @var \Web\BlogBundle\Entity\Users
     */
    private $user;

//Añadimos la propiedad $tagsPosts
    /**
     * @var \Web\BlogBundle\Entity\TagsPosts
     */
    protected $tagsPosts;

    public function __construct() {
        $this->tagsPosts = new ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId() {
        return $this->id;
    }

    /**
     * Set title
     *
     * @param string $title
     * @return Posts
     */
    public function setTitle($title) {
        $this->title = $title;

        return $this;
    }

    /**
     * Get title
     *
     * @return string 
     */
    public function getTitle() {
        return $this->title;
    }

    /**
     * Set description
     *
     * @param string $description
     * @return Posts
     */
    public function setDescription($description) {
        $this->description = $description;

        return $this;
    }

    /**
     * Get description
     *
     * @return string 
     */
    public function getDescription() {
        return $this->description;
    }

    /**
     * Set image
     *
     * @param string $image
     * @return Posts
     */
    public function setImage($image) {
        $this->image = $image;

        return $this;
    }

    /**
     * Get image
     *
     * @return string 
     */
    public function getImage() {
        return $this->image;
    }

    /**
     * Set content
     *
     * @param string $content
     * @return Posts
     */
    public function setContent($content) {
        $this->content = $content;

        return $this;
    }

    /**
     * Get content
     *
     * @return string 
     */
    public function getContent() {
        return $this->content;
    }

    /**
     * Set status
     *
     * @param string $status
     * @return Posts
     */
    public function setStatus($status) {
        $this->status = $status;

        return $this;
    }

    /**
     * Get status
     *
     * @return string 
     */
    public function getStatus() {
        return $this->status;
    }

    /**
     * Set date
     *
     * @param \DateTime $date
     * @return Posts
     */
    public function setDate($date) {
        $this->date = $date;

        return $this;
    }

    /**
     * Get date
     *
     * @return \DateTime 
     */
    public function getDate() {
        return $this->date;
    }

    /**
     * Set time
     *
     * @param \DateTime $time
     * @return Posts
     */
    public function setTime($time) {
        $this->time = $time;

        return $this;
    }

    /**
     * Get time
     *
     * @return \DateTime 
     */
    public function getTime() {
        return $this->time;
    }

    /**
     * Set category
     *
     * @param \Web\BlogBundle\Entity\Categories $category
     * @return Posts
     */
    public function setCategory(\Web\BlogBundle\Entity\Categories $category = null) {
        $this->category = $category;

        return $this;
    }

    /**
     * Get category
     *
     * @return \Web\BlogBundle\Entity\Categories 
     */
    public function getCategory() {
        return $this->category;
    }

    /**
     * Set user
     *
     * @param \Web\BlogBundle\Entity\Users $user
     * @return Posts
     */
    public function setUser(\Web\BlogBundle\Entity\Users $user = null) {
        $this->user = $user;

        return $this;
    }

    /**
     * Get user
     *
     * @return \Web\BlogBundle\Entity\Users 
     */
    public function getUser() {
        return $this->user;
    }

/* Añadimos estos dos métodos, aunque solamente utilizaremos el segundo para conseguir todas las tags de un post con una instancia de post. */
    /**
     * Add tagsPosts
     *
     * @param  Tag $tag
     * @return Course
     */
    public function addTagsPosts(\Web\BlogBundle\Entity\Tags $tag) {
        $this->tagsPosts[] = $tag;

        return $this;
    }

    /**
     * Get tagsPosts
     *
     * @return ArrayCollection
     */
    public function getTagsPosts() {
        return $this->tagsPosts;
    }

}

Con esto podremos hacer algo así:

   $tags=$post->getTagsPosts();
   foreach($tags as $t){
         var_dump($t->getTag()->getName());
   }

Y de esta forma sacar de forma muy fácil las tags de un post, sin hacer ningún tipo de join en SQL o con un query builder.

Tendremos que hacer lo mismo con la entidad de usuarios hacia la de posts, para al instanciar un usuario poder sacar todos sus posts.

También debemos hacer la relación OneToMany en la entidad categories para que cuando instanciemos una categoría podamos sacar todos los posts.

Más información:
Relaciones en Doctrine – Documentación oficial

Víctor Robles WEB

Autor: Victor

Desarrollador web - Formador online - Blogger

Compartir este post