2

I'm trying to do integration tests with Alice and some fixtures involving a recursive bi-directionnal relation.

class Node
{
    /** [...]
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /** [...]
     * @ORM\Column(name="name", type="string", length=100, nullable=false)
     */
    private $name;

    /** [...]
     * @ORM\ManyToOne(targetEntity="Node", inversedBy="children")
     */
    private $parent;

    /** [...]
     * @ORM\OneToMany(targetEntity="Node", mappedBy="parent")
     */
    private $children;

    // ...

    public function addChild(Node $child)
    {
        $this->children[] = $child;
        $child->setParent($this);

        return $this;
    }

    public function removeChild(Node $child)
    {
        $this->children->removeElement($child);
        $child->setParent(null);
    }

    // ...

Loading this fixture is well managed:

AppBundle\Entity\Node:
    Node-0:
        name: 'Trunk'
    Node-1:
        name: 'Branch 1'
        parent: '@Node-0'
    Node-2:
        name: 'Branch 2'
        parent: '@Node-0'

I can see the parent:

$loader = new NativeLoader();
$fixtures = $loader->loadFile('node.yml')->getObjects();
echo $fixtures['Node-1']->getParent()->getName();

Gives

Trunk

But the children don't seem to be populated:

echo count($fixtures['Node-0']->getChildren());

0

Am I missing something ? How can I find my children back ?

Pierre de LESPINAY
  • 44,700
  • 57
  • 210
  • 307

1 Answers1

0

Since the fixture is not persisted, Alice can only rely on how the setters/adders are implemented.

If the need is to add children to the nodes:

AppBundle\Entity\Node:
    Node-0:
        name: 'Trunk'
        children: ['@Node-1', '@Node-2']
    Node-1:
        name: 'Branch 1'
    Node-2:
        name: 'Branch 2'

This is the way to go:

public function addChild(Node $child)
{
    $this->children[] = $child;
    $child->setParent($this);

    return $this;
}

public function removeChild(Node $child)
{
    $this->children->removeElement($child);
    $child->setParent(null);
}

If the parent is defined in the fixture:

AppBundle\Entity\Node:
    Node-0:
        name: 'Trunk'
    Node-1:
        name: 'Branch 1'
        parent: '@Node-0'
    Node-2:
        name: 'Branch 2'
        parent: '@Node-0'

The parent setter have to be implemented like that:

public function setParent(Node $parent)
{
    $parent->addChild($this);
    $this->parent = $parent;

    return $this;
}

I guess we could even do some trick to manage both cases by avoiding the recursivity

Pierre de LESPINAY
  • 44,700
  • 57
  • 210
  • 307