RedactedProfile
RedactedProfile

Reputation: 2808

Doctrine - Select all from other table

I'm trying to basically run something like a sub-query to auto-hydrate a collection of Entities based on a basic join criteria. I'm not totally sure this is possible with just doctrine annotations, but I'd like to ask anyways.

So I have an entity known as "Page", which is kind of like an CMS entry. These Pages can have a mutable list of associated images with them. Basically its just another table with a page_id column in it. This table can associate any number of images with the same page_id, arranged by a sort. This entity is known as PageImage.

I'm basically just a noob with Doctrine and the @Join annotation directives throw my head for a spin right now.

So, load up a single page entity, and automatically populate a single attribute in the queried Page object with an array of PageImage entities. PageEntity has a page_id field.

I dont really have any code to share here as this is a question of approach. But lets see here:

Entities/Page.php

/**
 * Page
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Site\CoreBundle\Entity\PageRepository")
 */
class Page
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="page_title", type="string", length=255)
     */
    private $pageTitle;

    /**
     * @var string
     *
     * @Gedmo\Slug(fields={"pageTitle"})
     * @ORM\Column(name="slug", type="string", length=255)
     */
    private $slug;

    // NOT SURE WHAT TO DO HERE
    private $images;

}  

Entities/PageImage.php

/**
 * PageImage
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Site\CoreBundle\Entity\PageImageRepository")
 */
class PageImage
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="page_id", type="string", length=255)
     */
    private $page_id;

    /**
     * @var string
     *
     * @Assert\File(maxSize="6000000")
     * @ORM\Column(name="file", type="string", length=512)
     */
    private $file;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="dateAdded", type="datetime")
     */
    private $dateAdded;

    /**
     * @var integer
     *
     * @ORM\Column(name="sort", type="integer")
     */
    private $sort;

}

Upvotes: 0

Views: 1116

Answers (2)

lluisaznar
lluisaznar

Reputation: 2383

You have to make the relation between entities through Page.Images on one side, and PageImage.page_id on the other. I would do it as a OneToMany relation (one Page can have multiple PageImage). Check the documentation.

Code:

Page Entity:

/**
 * @OneToMany(targetEntity="PageImage", mappedBy="page_id")
 **/
private $images;

public function __construct() {
    $this->images = new \Doctrine\Common\Collections\ArrayCollection();
}

PageImage Entity:

/**
 * @ManyToOne(targetEntity="Page", inversedBy="images")
 * @JoinColumn(name="page_id", referencedColumnName="id")
 **/
private $page_id;

With these settings, Doctrine will handle the join and it will automatically populate the Page with its PageImage items related.

Upvotes: 1

Tuan nguyen
Tuan nguyen

Reputation: 570

In PageImage entity

use Doctrine\Common\Collections\ArrayCollection;

/**
 * PageImage
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Site\CoreBundle\Entity\PageImageRepository")
 */
class PageImage
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="Page", inversedBy="images")
     * @ORM\JoinColumn(name="page_id", referencedColumnName="id")
     */
    private $page;

    /**
     * @var string
     *
     * @Assert\File(maxSize="6000000")
     * @ORM\Column(name="file", type="string", length=512)
     */
    private $file;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="dateAdded", type="datetime")
     */
    private $dateAdded;

    /**
     * @var integer
     *
     * @ORM\Column(name="sort", type="integer")
     */
    private $sort;

}

In Page entity you declare variable 'images' as a ArrayCollection type (a Doctrine class used as a wrapper for basic array) in constructor. When fetching data, Doctrine will khow what image will be push into images collection based on your mapping.

/**
 * Page
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Site\CoreBundle\Entity\PageRepository")
 */
class Page
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="page_title", type="string", length=255)
     */
    private $pageTitle;

    /**
     * @var string
     *
     * @Gedmo\Slug(fields={"pageTitle"})
     * @ORM\Column(name="slug", type="string", length=255)
     */
    private $slug;

    /**
     * @ORM\OneToMany(targetEntity="PageImage", mappedBy="page")
     */
    private $images;

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

} 

Upvotes: 0

Related Questions