ApiGility - Returning custom collections

1.1k Views Asked by At

My goal is to return a custom collection for a findAll() query and to deliver this to HAL in order to ensure that its _links are formatted correctly. I originally thought I would simply do this programmatically however this seems to be the wrong way of doing this.

The problem I face is that the data I require is not from a single table, but rather from multiple tables (joins) and I am unable to work out how to do this properly.

I have the following entities:

Stone entity: A standard table with a join to some attributes that I would like to return in my feed

/**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @ORM\ManyToMany(targetEntity="Stone\Entity\StAttribute")
     * @ORM\JoinTable(name="st_stone_attribute",
     *      joinColumns={@ORM\JoinColumn(name="stone_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="attribute_id", referencedColumnName="id")}
     * )
     *
     * @var Collection
     * @access private
     */
    private $attribute;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=50, nullable=false)
     */
    private $name;

etc...

The attribute entity is a standard table:

/**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=30, nullable=false)
     */
    private $name;

My resource calls:

public function fetchAll($params = array())
    {
        return $this->stoneMapper->fetchAll();
    }

My mapper file:

public function fetchAll()
{
    $qb   = $this->stoneRepository->createQueryBuilder('u')
        ->where('u.state=:state')
        ->setParameter('state' , 1 );

    $adapter    = new DoctrineAdapter( new ORMPaginator( $qb ) );
    $collection = new StoneCollection($adapter);

    return $collection;
}

My collection

use Zend\Paginator\Paginator;

class StoneCollection extends Paginator
{

}

Screen shot of the results here: http://screencast.com/t/vgm34s92dsk2

As you can see from the screen shot "attribute" and other similar fields are not being populated...

So my question is this: how do I ensure that the join tables are populated in the feed?

1

There are 1 best solutions below

0
On

You will need to fetch join your associations. You can read on this in the Doctrine 2 documentation here.

In your case it would look as follows:

$qb = $this->stoneRepository->createQueryBuilder('s')
    ->addSelect('a')
    ->leftJoin('s.attribute', 'a')
    ->where('s.state = :state')
    ->setParameter('state' , 1 );

It will also be necessary to have either a hydrator for your StAttribute in your MetadataMap or there should otherwise be some code implemented to extract the StAttribute properties.

You can of course also do this in the fetch method itself, but that is not so pretty.

The object will continue to render as {} in case you do not extract or convert the object to something that can be serialized to valid json format (either a Hal resource or collection instance, a (json) string or a JsonSerializable).