Reputation: 2418
I have entity which has multiple Photos:
/**
* related images
* @ORM\OneToMany(targetEntity="Photo", mappedBy="entity",cascade={"persist"})
* @ORM\OrderBy({"uploaded_at" = "ASC"})
*/
private $photos;
Photos have ManyToOne relation with entity
/**
* @ORM\ManyToOne(targetEntity="Acme\AppBundle\Entity\Entity", inversedBy="photos")
* @ORM\JoinColumn(name="entity_id", referencedColumnName="id", onDelete="CASCADE")
*/
private $entity;
all setters and getter are set I'm foliving symfony collection documentation: http://symfony.com/doc/current/reference/forms/types/collection.html
FormType:
->add('photos', 'collection', array(
'type' => new PhotoFormType(),
'allow_add' => true,
'by_reference' => false,
'allow_delete' => true,
'prototype' => true
))
PhotoType:
$builder
->add('title', null, ['label' => 'front.photo.title', 'required' => true])
->add('image', 'file', array('required' => false))
;
For upload I'm using vichUploadableBundle, Images are save just fine, but entity_id is not save and has null. I don't know what I did miss here.
Upvotes: 4
Views: 5746
Reputation: 823
I've went to this also. I think the main problem is that even the main entity has cascade={"persist"} , the child entites do not get the ID when you are creating a new entry. So what I did, that is kind of a hack, but works fine is this.
// $em->persist($entity); After persisting entity:
foreach ($entity->getPhotos() as $photo) {
$photo->setEntity($entity);
}
Basically persisting the ID in the childs after their father is created.
But on another point, at least how I understand Doctrine, please correct me if I'm wrong. Try to add an orphanRemoval / fetch additional properties:
FATHER Entity has:
/**
* Related images.
* @ORM\OneToMany(targetEntity="Photo", mappedBy="entity", cascade={"persist"}, orphanRemoval=true, fetch="EAGER")
* @ORM\OrderBy({"uploaded_at" = "ASC"})
*/
private $photos;
Upvotes: 3
Reputation: 308
Following would be best solution on this issue so far investigate or research with symfony form component.
FormType:
->add("photos",'collection', array(
'type' => new PhotoFormType(),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false
))
Entity class
public function addPhoto(Photo $photo)
{
$photo->setEntity($this);
$this->photos->add($photo);
}
public function removePhoto(Photo $photo)
{
$this->photos->removeElement($photo);
}
Best practice is not to use loop to bind reference entity manually . Remember by_reference must be false. like 'by_reference' => false.
Upvotes: 6
Reputation: 91
Run into the same issue, still I remember there is better solution.
You need to specify add and remove functions in the entity with collection.
class Entity
{
// ...
public function addPhoto(Photo $photo)
{
$this->photos->add($photo);
$photo->setEntity($this);
}
public function removePhoto(Photo $photo)
{
$this->photos->removeElement($photo);
}
}
So in such a case you wouldn't need a loop in the controller. Also if
orphanRemoval=true
is set, no problems with delete.
Upvotes: 4
Reputation: 2418
Photo Entity is persisted so I add to controller handler to set for every photo Entity. Don't know if it's right solution but it's working.
/** @var Photo $photo */
foreach ($entity->getPhotos() as $photo){
$photo->setEntity($entity);
$em->persist($photo);
}
Upvotes: 0