Symfony 4 when entity field change, change field in another entity

631 Views Asked by At

I have two entities for example:

class Dog
{

    /**
     * @var House
     *
     * @ORM\ManyToOne(targetEntity="House")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="house_id", referencedColumnName="id")
     * })
     */
    private $house;
}

class House
{

     /**
     * @var ArrayCollection|null
     * @ORM\ManyToMany(targetEntity="Dog",cascade={"persist"})
     * @ORM\JoinColumns({
     * @ORM\JoinColumn(name="dog_id", referencedColumnName="id", nullable=true)
     * })
     */
    protected $dog;
}

I need to throw an event if field house in Entity Dog was update (set or remove) then add or remove field dog in Entity House. Can anyone show me how do this ?

2

There are 2 best solutions below

2
On

You must call $dog->setHouse($this); from the addDog method. If you used the commandline then below class House would be generated for you.

class House
{
    // ...

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Dog", mappedBy="house")
     */
    private $dogs;

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

    public function getId(): ?int
    {
        return $this->id;
    }

    /**
     * @return Collection|Dog[]
     */
    public function getDogs(): Collection
    {
        return $this->dogs;
    }

    public function addDog(Dog $dog): self
    {
        if (!$this->dogs->contains($dog)) {
            $this->dogs[] = $dog;
            $dog->setHouse($this);       // <-- here you go
        }

        return $this;
    }

    public function removeDog(Dog $dog): self
    {
        if ($this->dogs->contains($dog)) {
            $this->dogs->removeElement($dog);
            // set the owning side to null (unless already changed)
            if ($dog->getHouse() === $this) {
                $dog->setHouse(null);
            }
        }

        return $this;
    }
}

Same thing counts for removeDog() method.

1
On

Doctrine will do this for you but depending on the cascade option. But your annotations are not correct. In the Dog entity you have annotation for a ManyToOne and in the House entity for a ManyToMany relation. But you should choose between

  1. ManyToOne - OneToMany
  2. ManyToMany - ManyToMany

Take a look into the Doctrine's association mapping to read about all the types of associations and how to define them.

If you are using Symfony (4 or 5) you should use the commandline make tool to add properties and methods with all the annotations, even for relations.

bin/console make:entity Dog

Type relation when asked for the Field type and you will have to answer some additional questions.