@AlexKuznec

Symfony удаляет лишние связи ManyToMany при использовании фильтра. Как победить?

Использую Symfony 3.3

У меня есть 2 таблицы (Entity) User и Project со стандартной связью
@ORM\ManyToMany

В стандартной форме стандартного контроллера пользователь может выбрать чекбоксами наличие связей между User и списком отфильтрованных Project (не все отображаются).

Для фильтрации использую наследника SQLFilter (такой же фильтр использует SoftDeleteable).

Проблема в том, что если снять последний чекбокс, то удаляются вообще все связи из базы, включая те, что были отфильтрованы и не отображались в списке.

Запускается такой запрос:
DELETE FROM user_project WHERE user_id = ?

вместо обычного запроса
DELETE FROM user_project WHERE user_id = ? AND project_id = ?

Попытка как-то повлиять на процесс привела к тестированию происходящего через использование в форме
$builder->get('projects')
            ->addModelTransformer(new CallbackTransformer(...

К нему поступают данные класса \Doctrine\ORM\PersistentCollection содержащего мои объекты Project.
Там есть 2 полезных метода:
getSnapshot() - возвращает массив объектов до изменения
getDeleteDiff() - массив объектов на удаление (разница между текущим состоянием и Snapshot)

Прикол в том, что при удалении последнего элемента они оба оказываются пустыми. Как?
То есть поведение такое:

Количество связей: Элементов Snapshot: Элементов getDeleteDiff():
3 -> 2 .......................................... 3 ................................................ 1
2 -> 1 .......................................... 2 ................................................ 1
1 -> 0 .......................................... 0 ................................................ 0

То есть я даже удаляемый объект не могу использовать для перестроения коллекции, так как он бесследно исчез!

В идеале хотелось бы добавить фильтр к запросу DELETE (к SELECT он автоматом добавляется, а к DELETE - нет), пусть даже как-нибудь вручную.

Ну или хотя бы предотвратить удаление элементов без их номеров.
  • Вопрос задан
  • 165 просмотров
Решения вопроса 1
@AlexKuznec Автор вопроса
Решилось очень просто)
Надо было установить свойство формы 'by_reference' => false, после чего начал использоваться метод удаления из моего Entity (переданного в форму), а не на автомате. Причем данное свойство по документации вроде как должно влиять на использование методов связанной сущности, а не переданной в форму. В трансформер вместо PersistentCollection начала передаваться ArrayCollection, видимо, из моего геттера.

Вот тут упоминание об этом есть (основная тема, что связи не сохраняются):
https://afilina.com/doctrine-not-saving-manytomany

Однако вопрос прикрепления фильтра к запросу DELETE все еще актуален. Чтобы наверняка защитить данные.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы