Symfony4 - Как обновить доктрину ArrayCollection?

У меня есть член моей сущности - arrayCollection. С классическим конструктором форм работает нормально, я могу выбрать несколько элементов и сохранить их. Но когда я пытаюсь обновить объект в контроллере, я получаю сообщение об ошибке: «Вызов функции-члена setFaavailability () в массиве».

Резюме моей организации:

/**
 * @ORM\ManyToOne(targetEntity = "App\Entity\FaAvailability", 
   inversedBy = "faavailability")
 * @ORM\JoinColumn(nullable=true)
 * @ORM\Column(type = "array")
 */
 public $faavailability;

 /**
 * @return mixed
 */
public function getFaavailability()
{
    return $this->faavailability;
}

/**
 * @param mixed $faavailability
 */
public function setFaavailability($faavailability)
{
    $this->faavailability = $faavailability;
}

В моем контроллере:

 $varFaavailability = $animal->faperson->getFaavailability();
 foreach($varFaavailability as $availability){
         if ($availability->getName() == $animal->typepet->getName()){
           $varFaavailability->removeElement($availability);
           $faPerson = $em->getRepository(FaPerson::class) >findById($animal->faperson->getId());
           $faPerson->setFaavailability($varFaavailability);
           $em->persist($faPerson);
           $em->flush();
         }
}

Любые идеи ?

Попробуйте удалить "@ORM \ Column (type = " array ")" из аннотаций $ faavailability.

Jannes Botis 27.12.2018 23:58

Отношение ManyToOne, не возвращает arrayCollection, Only ManyToMany или oneToMany

hous 29.12.2018 21:33
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
2
3 736
3

Ответы 3

Если я хорошо помню, когда вы устанавливаете поле как ArrayCollection, это означает, что у вас есть отношение oneToMany между двумя объектами. Из вашего кода я могу сказать вам, что вы пытаетесь сохранить данные в неправильном объекте. Обычно вы добавляете owning_entity_id (1-to-N) в каждый элемент (1-to-N) и сохраняете его. В своем коде вы пытаетесь установить все ссылки сразу, чего никогда не произойдет. Удалите setFaavailability () или заново определите отношения сущностей.

Никогда не следует пытаться массово добавлять отношения внешнего ключа в одну функцию установки super duper. Прокрутите все элементы и установите ссылку на «родительский» объект.

Проблема в этой части: $faPerson = $em->getRepository(FaPerson::class)->findById($animal->faperson->getId());

Методы findBy* попытаются найти несколько объектов и вернуть их в Collection. Если вы ищете одного человека, вы можете использовать вместо него findOneById. Или (при условии, что id настроен как идентификатор в Doctrine) вы даже можете использовать метод find: $faPerson = $em->getRepository(FaPerson::class)->find($animal->faperson->getId());

С вашим решением у меня нет ошибки, но она ничего не сохраняет. Ты знаешь почему ?

user3659832 28.12.2018 15:27

Вам, вероятно, потребуется настроить каскадирование, чтобы также сохранить доступность, когда вы сохраняете человека. Вы можете сделать это с помощью каскада "persist": doctrine-project.org/projects/doctrine-orm/en/2.6/reference/‌…

Timo 02.01.2019 12:34

некоторые общие комментарии:

  1. В Doctrine вам никогда не придется работать с идентификаторами. Использовать сущность объекты! Вам нужно только findById, если вы получили идентификатор, например, из параметра запроса.
  2. Вам следует пересмотреть наименования ваших переменных, чтобы было ясно, является ли это коллекцией ($ Availability) или отдельной ($ availability).
  3. Всегда используйте методы получения / установки вместо полей (typepet vs getTypepet ()).
  4. Вызовите flush () один в конце, чтобы обновить все сущности в одной транзакции.

Я переименовал переменные ниже, как я их понял. Однако я до сих пор не уверен, что возвращает $ animal-> faperson-> getFaavailabilities (), поскольку вначале вы хотите просмотреть результаты в цикле, а затем установить его на один с помощью setFaavailability ()?

 //Should be a Doctrine ArrayCollection
 $varFaavailabilities = $animal->faperson->getFaavailabilities();

 foreach($varFaavailability as $availability){
         if ($availability->getName() == $animal->getTypepet()->getName()) {

           //Why do you want to remove an element from the current loop?
           $varFaavailability->removeElement($availability);

           //No need to use Id
           $faPerson = $animal->getFaperson();

           //A single one?
           $faPerson->setFaavailability($availability);

           //More than one? addFaavailability should exist.
           $faPerson->addFaavailability($availability);

           $em->persist($faPerson);

         }
}
$em->flush();

Да ты прав, этот код лучше. Я просто хочу удалить один элемент из arrayCollection, когда условие if истинно. если я выполняю $ faPerson-> setFaavailability ($ varFaavailability), в свойстве Faavailability ничего не сохраняется. Я меняю на $ faPerson-> setFaavailability ($ varFaavailability-> removeEleme‌ nt ($ availability)) Сохраняется значение «1» ... Это очень странно. У тебя есть идея?

user3659832 28.12.2018 20:51

Просто вызовите $ varFaavailability-> removeElement ($ availability); без setFaavailability ()

Arne 29.12.2018 21:09

Другие вопросы по теме