Magento Attribute effizient inkrementieren & dekrementieren

Diese Frage tauchte auf Magento StackExchange auf:

I need to decrement a value with an atomic database operation, is it possible using Magento models?

Es ist tatsächlich möglich, Attribute mit einem Update zu inkrementieren und dekrementieren und zwar mit einer weniger bekannten Technik mittels Zend_Db_Expr. Ich teile es auch hier:

$object->setNumber(new Zend_Db_Expr('number-1'));

Als Referenz:

Die Methode Mage_Core_Model_Resource_Abstract::_prepareDataForSave() enthält folgenden Code:

if ($object->hasData($field)) {
    $fieldValue = $object->getData($field);
    if ($fieldValue instanceof Zend_Db_Expr) {
        $data[$field] = $fieldValue;
    } else {
        ... [normale Verarbeitung folgt]

EAV Models:

Beachte, dass man das Attribut nur mit seinem Namen referenzieren kann (“number” im Beispiel) wenn es eine echte Spalte der Haupt-Tabelle ist, kein EAV-Attribut.

Obwohl die obengenannte Methode nur von Models mit flachen Tabellen benutzt wird, kann Zend_Db_Expr aber auch für EAV Attribute benutzt werden, die Methode die den Parameter verarbeitet, ist Varien_Db_Adapter_Pdo_Mysql::prepareColumnValue().

ABER man muss dann immer den Spaltennamen “value” verwenden:

$product->setNumber(new Zend_Db_Expr('value-1'));

Es ist nicht notwendig, einen Alias für die Tabelle anzugeben, weil jedes Attribue einzeln mit eigenem Query verarbeitet wird, so dass “value” nicht mehrdeutig ist.