MicWit MicWit - 1 month ago 10
Twig Question

Check not records exist for one to many in Symfony/Doctrine

I have a relationship that is one to many. I have maps (each block is a separate map) and rooms (each map will have multiple rooms). So for the entities (I will cut out info not needed) I have:

/**
* Block
*
* @ORM\Table(name="BLOCK")
* @ORM\Entity
*/
class Block
{
/**
* @var integer
*
* @ORM\Column(name="PK", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="SEQUENCE")
* @ORM\SequenceGenerator(sequenceName="SEQ_GET_BLOCK_PK", allocationSize=1, initialValue=1)
* @ORM\OneToMany(targetEntity="Rooms", mappedBy="blockId")
*/
private $pk;
}

/**
* Rooms
*
* @ORM\Table(name="ROOMS", indexes={@ORM\Index(name="IDX_EB2CE87E9B70DE02", columns={"MAP_ID"})})
* @ORM\Entity
*/
class Rooms
{
/**
* @var integer
*
* @ORM\Column(name="PK", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="SEQUENCE")
* @ORM\SequenceGenerator(sequenceName="SEQ_GET_ROOMS_PK", allocationSize=1, initialValue=1)
*/
private $pk;

/**
* @var \Block
*
* @ORM\ManyToOne(targetEntity="Block")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="BLOCK_ID", referencedColumnName="PK")
* })
*/
private $block;


Now to get what block belongs to a room, that's simple, in the controller:

$roomRepo = $this->getDoctrine()->getRepository('AppBundle:Rooms');
$rooms = $roomRepo->findAll();


and in Twig (where fieldname is another field in the block table):

{% for room in rooms %}
{{ room.block.fieldname }}
{% endfor %}


However, to display a list of blocks and show the rooms under them becomes harder. I would like to be able to get the list of blocks and do something in Twig like:

{% for block in blocks %}
{% for room in block.rooms %}
{{ room.name }}
{% endfor %}
{% endfor %}


In this situation, I am trying to get a list of blocks that do not have any rooms under them. If the solution above worked, I could just do a count of rooms in each block and only display if there is none. The other option is to make the query do the count in createQueryBuilder and return the entity block with the correct results.

Any ideas? I keep looking down these paths but hit walls after a bit.

Answer

It seems like you need One-to-Many bidirectional relation: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#one-to-many-bidirectional

Is the $pk property in Block a primary key? Then it can't have the annotation @ORM\OneToMany and you should have a separate property with a collection of rooms:

/** @OneToMany(targetEntity="Rooms", mappedBy="block") */
private $rooms;

and then on Room class:

/**
 * @ManyToOne(targetEntity="Block", inversedBy="rooms")
 * @JoinColumn(name="BLOCK_ID", referencedColumnName="PK")
 */
private $block;

Your use case seems exactly the same like the one in the documentation so I recommend following their example.

Comments