Home > Blockchain >  How can I add a OneToMany field in Symfony?
How can I add a OneToMany field in Symfony?

Time:06-16

I try to configure a OneToMany field to my Symfony app:

my Entity: Project.php

 /**
* @ORM\OneToMany(targetEntity="App\Entity\Event", mappedBy="project")
*/
private $event;


public function __construct()
{
    $this->enabled = false;
    $this->event = new ArrayCollection();
}


public function getEvent()
{
    return $this->event;
}

public function setEvent($event): self
{
    $this->event = $event;

    return $this;
}

public function addEvent(Event $event): self
{
    $this->event[] = $event;

    return $this;
}

public function removeEvent(Event $event)
{
    if ($this->event->contains($event)) {
        $this->event->removeElement($event);
        $event->removeEvent($this);
    }

    return $this;
}

my Entity event.php

 /**
 * @ORM\ManyToOne(targetEntity="App\Entity\Project", inversedBy="event")
 * @ORM\JoinColumn(nullable=false)
 */
 private $project;

my Controller ProjectController.php

  protected function mapDataToEntity(array $data, Project $entity): void{
    if ($event = $data['event'] ?? null) {
            foreach ($event as $e) {
                $entity->setEvent($e);
            }
            
     }
  }

But I get the error message:

SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (mysite.#sql-172bb_1b3, CONSTRAINT FK_ED7D872A166D1F9I FOREIGN KEY (project_id) REFERENCES app_project (id))

What am I missing?

CodePudding user response:

Did you change something in entity after migration ? Try to delete table, run php bin/console doctrine:schema:update --force and check with php bin/console doctrine:migrations:migrate. Also you can delete set method, this will be collection.

CodePudding user response:

As stated in the documentation,:

To update a relationship in the database, you must set the relationship on the owning side. The owning side is always where the ManyToOne mapping is set.

So when persisting the Event the related Project is not set, and the constraint fails. You should be calling $event->setProject();.

MakerBundle would usually autogenerate the code to do it from the inverse side (Project, in this instance), but that bit is missing from your code. You can regenerate the entities using the bundle (bin/console make:entity Project --regenerate should do it) or add the bit that's missing, since I don't think you are using the bundle:

// Project.php
public function addEvent(Event $event): self
{
    if (!$this->event->contains($event)) {
        $this->event[] = $event;
        $event->setProject($this);  // This is the crucial line
    }

    return $this;
}

As a side note, I'd rename the property to events, since it clearly denotes a collection, but that's irrelevant for this issue. Those kinds of little details would be taken care of by using MakerBundle.

Also, as noted by @Maniax in the comments, the controller should read

foreach ($event as $e) {
    $entity->addEvent($e);
}
  • Related