#php #symfony #many-to-one #symfony5
#php #symfony #многие к одному #symfony5
Вопрос:
Здравствуйте, я не могу сохранить данные моей формы. Это работает только с одной стороны.
Форма «Target» позволяет создавать цели и связывать их с действиями: все в порядке.
В моей форме «Действия» у меня также есть поле «Цель», в котором отображаются связанные цели, но, похоже, я не могу их изменить. Мой выбор сохраняется только на стороне «целевой» формы.
Я только хочу иметь возможность выбирать некоторые из них на странице активности, не более того.
TargetType.php :
<?php
namespace AppForm;
use AppEntityTarget;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolver;
class TargetType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('activity')
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Target::class,
]);
}
}
ActivityType.php :
<?php
namespace AppForm;
use AppEntityActivity;
use AppEntityTarget;
use SymfonyBridgeDoctrineFormTypeEntityType;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolver;
class ActivityType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('targets', EntityType::class, [
'class' => Target::class,
'expanded' => false,
'multiple' => true,
])
->add('types')
->add('packs')
->add('partners')
->add('places')
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Activity::class,
]);
}
}
Целевая сущность :
<?php
namespace AppEntity;
use AppRepositoryTargetRepository;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use DoctrineORMMapping as ORM;
/**
* @ORMEntity(repositoryClass=TargetRepository::class)
*/
class Target
{
/**
* @ORMId
* @ORMGeneratedValue
* @ORMColumn(type="integer")
*/
private $id;
/**
* @ORMColumn(type="string", length=255)
*/
private $name;
/**
* @ORMManyToMany(targetEntity=Activity::class, inversedBy="targets", cascade={"persist"})
*/
private $activity;
public function __construct()
{
$this->activity = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
/**
* @return Collection|Activity[]
*/
public function getActivity(): Collection
{
return $this->activity;
}
public function addActivity(Activity $activity): self
{
if (!$this->activity->contains($activity)) {
$this->activity[] = $activity;
}
return $this;
}
public function removeActivity(Activity $activity): self
{
if ($this->activity->contains($activity)) {
$this->activity->removeElement($activity);
}
return $this;
}
public function __toString()
{
return
$this->name;
}
}
Объект активности :
<?php
namespace AppEntity;
use AppRepositoryActivityRepository;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use DoctrineORMMapping as ORM;
use SymfonyComponentValidatorConstraints as Assert;
/**
* @ORMEntity(repositoryClass=ActivityRepository::class)
*/
class Activity
{
/**
* @ORMId
* @ORMGeneratedValue
* @ORMColumn(type="integer")
* @AssertValid()
*/
private $id;
/**
* @ORMColumn(type="string", length=255)
*/
private $name;
/**
* @ORMManyToMany(targetEntity=Target::class, mappedBy="activity",cascade={"persist"})
*/
private $targets;
/**
* @ORMManyToMany(targetEntity=Type::class, mappedBy="activity")
*/
private $types;
/**
* @ORMManyToMany(targetEntity=Pack::class, mappedBy="activity")
*/
private $packs;
/**
* @ORMManyToMany(targetEntity=Partner::class, mappedBy="activity")
*/
private $partners;
/**
* @ORMManyToMany(targetEntity=Place::class, mappedBy="activity")
*/
private $places;
/**
* @ORMOneToMany(targetEntity=Gallery::class, mappedBy="activity")
*/
private $image;
public function __construct()
{
$this->targets = new ArrayCollection();
$this->types = new ArrayCollection();
$this->packs = new ArrayCollection();
$this->partners = new ArrayCollection();
$this->places = new ArrayCollection();
$this->image = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
/**
* @return Collection|Target[]
*/
public function getTargets(): Collection
{
return $this->targets;
}
public function addTarget(Target $target): self
{
if (!$this->targets->contains($target)) {
$this->targets[] = $target;
$target->addActivity($this);
}
return $this;
}
public function removeTarget(Target $target): self
{
if ($this->targets->contains($target)) {
$this->targets->removeElement($target);
$target->removeActivity($this);
}
return $this;
}
/**
* @return Collection|Type[]
*/
public function getTypes(): Collection
{
return $this->types;
}
public function addType(Type $type): self
{
if (!$this->types->contains($type)) {
$this->types[] = $type;
$type->addActivity($this);
}
return $this;
}
public function removeType(Type $type): self
{
if ($this->types->contains($type)) {
$this->types->removeElement($type);
$type->removeActivity($this);
}
return $this;
}
/**
* @return Collection|Pack[]
*/
public function getPacks(): Collection
{
return $this->packs;
}
public function addPack(Pack $pack): self
{
if (!$this->packs->contains($pack)) {
$this->packs[] = $pack;
$pack->addActivity($this);
}
return $this;
}
public function removePack(Pack $pack): self
{
if ($this->packs->contains($pack)) {
$this->packs->removeElement($pack);
$pack->removeActivity($this);
}
return $this;
}
/**
* @return Collection|Partner[]
*/
public function getPartners(): Collection
{
return $this->partners;
}
public function addPartner(Partner $partner): self
{
if (!$this->partners->contains($partner)) {
$this->partners[] = $partner;
$partner->addActivity($this);
}
return $this;
}
public function removePartner(Partner $partner): self
{
if ($this->partners->contains($partner)) {
$this->partners->removeElement($partner);
$partner->removeActivity($this);
}
return $this;
}
/**
* @return Collection|Place[]
*/
public function getPlaces(): Collection
{
return $this->places;
}
public function addPlace(Place $place): self
{
if (!$this->places->contains($place)) {
$this->places[] = $place;
$place->addActivity($this);
}
return $this;
}
public function removePlace(Place $place): self
{
if ($this->places->contains($place)) {
$this->places->removeElement($place);
$place->removeActivity($this);
}
return $this;
}
/**
* @return Collection|Gallery[]
*/
public function getImage(): Collection
{
return $this->image;
}
public function addImage(Gallery $image): self
{
if (!$this->image->contains($image)) {
$this->image[] = $image;
$image->setActivity($this);
}
return $this;
}
public function removeImage(Gallery $image): self
{
if ($this->image->contains($image)) {
$this->image->removeElement($image);
// set the owning side to null (unless already changed)
if ($image->getActivity() === $this) {
$image->setActivity(null);
}
}
return $this;
}
public function __toString()
{
return
$this->name;
}
}
Ответ №1:
Вам нужно принудительно вызвать установщик Target
в вашем ActivityType
, установив by_reference
для свойства значение false
:
class ActivityType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('targets', EntityType::class, [
'class' => Target::class,
'expanded' => false,
'multiple' => true,
'by_reference' => false // <- done in this line here
])
// ...
Больше информации в документах здесь :
https://symfony.com/doc/current/reference/forms/types/collection.html#by-reference