PHP/Propel удалить запись 1:n

У меня есть две таблицы: шаг и ссылки соединились 1:n. Я стремлюсь поддерживать ссылки через объекты шага. Я извлекаю все шаги из базы данных и заполняю связь таблицей ссылок. Я сохраняю объект шага, содержащий коллекцию ссылок на JSON, и возвращаю его внешнему интерфейсу с помощью REST.

Это означает, что если какой-либо шаг связан или не связан с другим шагом во внешнем интерфейсе, я отправляю весь шаг обратно в бэкэнд, включая коллекцию ссылок. В конце я использую следующий код:

public function put($processStep) {
        if (isset($processStep['Processesid']) && isset($processStep['Coordx']) && isset($processStep['Coordy'])) {
            $p = $this->query->findPK($processStep['Id']);

            $p->setId($processStep['Id']);
            $p->setProcessesid($processStep['Processesid']);
            if (isset($processStep['Flowid'])) $p->setFlowid($processStep['Flowid']);
            if (isset($processStep['Applicationid'])) $p->setApplicationid($processStep['Applicationid']);
            $p->setCoordx($processStep['Coordx']);
            $p->setCoordy($processStep['Coordy']);

            $links = $p->getLinksRelatedByFromstep();
            $links->clear();

            foreach ($processStep['Links'] as $link) {
                if (!isset($link['Linkid'])) {
                    $newLink = new \Link();

                    $newLink->setFromstep($link['Fromstep']);
                    $newLink->setTostep($link['Tostep']);

                    $links->prepend($newLink);
                }
            }

            $p->save();

            return $p;
        } else {
            throw new Exceptions\ProcessStepException("Missing mandatory fields.", 1);
        }
    }

Я в основном удаляю каждую ссылку из шага и на основе объекта запроса воссоздаю ссылки. Это избавляет меня от необходимости сравнивать, какие ссылки удаляются и добавляются. Вставка работает как брелок Propel автоматически создает новые ссылки. Дело в том, что он не удаляет, как он вставляет. Я проверил объект, который сохраняется ($p), и вижу, что ссылка удалена, но в журнале MySQL Propel не выполняет никаких действий. Похоже, что отсутствующий элемент из коллекции ссылок не вызывает грязный флаг или что-то в этом роде.

Может быть, я поступаю неправильно, надеюсь, кто-нибудь может дать какой-нибудь совет.

Спасибо

2 ответа

Решение

Благодаря Бену я оказался на правильном пути, явный вызов для удаления не нужен. Я натолкнулся на функцию с именем: setRelatedBy(ObjectCollection o). Я использую эту функцию для предоставления списка связанных объектов, новые объекты интерпретируются как вставки, а пропуски интерпретируются как удаления.

Я не нашел соответствующей документации по проблеме, вот мой код:

$p = $this->query->findPK($processStep['Id']);

            $p->setId($processStep['Id']);
            $p->setProcessesid($processStep['Processesid']);
            $p->setCoordx($processStep['Coordx']);
            $p->setCoordy($processStep['Coordy']);
            if (isset($processStep['Flowid'])) $p->setFlowid($processStep['Flowid']);
            if (isset($processStep['Applicationid'])) $p->setApplicationid($processStep['Applicationid']);

            //Get related records, same as populaterelation
            $currentLinks = $p->getLinksRelatedByFromstep();
            $links =  new \Propel\Runtime\Collection\ObjectCollection();

            //Check for still existing links add to new collection if so.
            //This is because creating a new Link instance and setting columns marks the object as dirty creating an exception due to duplicate keys
            foreach ($currentLinks as $currentLink) {
                foreach ($processStep['Links'] as $link) {
                    if (isset($link['Linkid']) && $currentLink->getLinkid() == $link['Linkid']) {
                        $links->prepend($currentLink);

                        break;
                    }
                }
            }

            //Add new link objects
            foreach ($processStep['Links'] as $link) {
                if (!isset($link['Linkid'])) {
                    $newLink = new \Link();

                    $newLink->setFromstep($link['Fromstep']);
                    $newLink->setTostep($link['Tostep']);

                    $links->prepend($newLink);
                }

            }

            //Replace the collection and save the processstep.
            $p->setLinksRelatedByFromstep($links);
            $p->save();

Чтобы удалить записи, вы всегда должны использовать delete, diff Метод в коллекции чрезвычайно полезен при определении того, какие объекты нужно добавить, обновить и удалить.

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