«Подделка» существующего объекта
Propel выбирает между вставкой и обновлением на основе результата вызова isNew()
для объекта, который вы хотите сохранить (см. Вашу функцию BaseCategory::save()
: $isInsert = $this->isNew();
). Поэтому вы можете обмануть его, думая, что это существующий объект, изменив это свойство самостоятельно: $mo->setNew(false);
. isNew()
и setNew()
определены в BaseObject
классе .
В целом, может быть, не очень хорошая идея работать с частично гидратированными объектами (что вы, похоже, делаете здесь: вы создаете объект, но затем не заполняете все свойства их фактической базой данных ценности). Некоторые варианты поведения или ваш собственный код могут зависеть от двух свойств объекта и приводить к неверным результатам. Упрощенный пример: если у вас есть автоматически сгенерированное поле nameAndDescription
, которое вы задаете для конкатенации полей name
и description
при сохранении (путем расширения объекта Propel с помощью новых preInsert()
и preUpdate()
ловит), это не будет делать то, что вы ожидаете, если вы обновите свой объект, как вы делаете это здесь. Но это единственное предупреждение, которое я знаю, и, вероятно, это ситуация, которую вы держите под контролем.
Обновление полей без создания объекта
Если вы хотите обновить только некоторые поля и, возможно, даже для нескольких объектов (например: для всех Order
объектов с executionDate
до сегодняшнего дня, установите status
в "archived"
), вы можете сделать позвоните BasePeer::doUpdate()
сами. Первым аргументом является выбранный вами объект Criteria: все Order
объектов с executionDate
до сегодняшнего дня. Второй аргумент также является объектом Criteria, но он используется для хранения новых значений: от status
до "archived"
. Это должно выглядеть так (не проверено):
// This probably also works with a Query object
$selectCriteria = new Criteria(OrderPeer::DATABASE_NAME);
$selectCriteria->add(OrderPeer::EXECUTION_DATE, time(), Criteria::LESS_THAN);
// And this too, it's just used as a simple hash table
$valueCriteria = new Criteria(OrderPeer::DATABASE_NAME);
$valueCriteria->add(OrderPeer::STATUS, "archived");
$con = Propel::getConnection(OrderPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
BasePeer::doUpdate($selectCriteria, $valueCriteria, $con);
Этот метод, конечно, не будет выполнять никаких хуков preUpdate()
или postUpdate()
, которые вы определили в коде PHP, так как сгенерированные объекты полностью обойдены. Так что используйте его только тогда, когда это абсолютно необходимо (из соображений производительности?), И вы знаете, что вокруг нет других "устаревших" объектов.