4

I'm confused by the way Magento's ORM behaves when editing/saving an object; see the example below:

$model = Mage::getModel('vendor/model')
    ->setData(array(
        'name'        => 'Test,
        'description' => 'Info',
    ))
    ->save();

I now have a new record in the table, however this is where i'm confused.

$model = Mage::getModel('vendor/model')->load(1);
$model->setName('Test');  // THIS IS THE SAME
$model->setDescription('Info'); // THIS IS THE SAME

var_dump($model->hasDataChanges()); // returns true! (i expect false)
var_dump(($model->getData() !== $model->getOrigData())) // returns false (expected)

Surely the latter is how Magento should behave? Unless i'm missing something.

3
  • 1
    As David points out, this is a programmatic intent (opinion) in the framework. Not sure if this is to reduce overhead of always checking if being-set value is == to current value, but that's simply the way it's written.
    – benmarks
    Commented Jan 7, 2014 at 18:16
  • @benmarks Hmm okay. The way that I looked at it was one could simply parse an array of data to setData then save, but this would query the database unnecessarily which surely it's more efficient for php to condition whether changes exist. Either way, I was only curious since I used the latter example above anyway, understanding I suppose.
    – Ash
    Commented Jan 7, 2014 at 21:23
  • 1
    You've asked a pertinent question here, one I've heard it many times in the Fundamentals class. I'm not aware of / smart enough to know the basis for this ORM opinion. FYI you can compare ORM object's _origData array _data, though for the purpose of write logic _data may contain extraneous members which are not persisted (i.e. no corresponding attribute or column).
    – benmarks
    Commented Jan 8, 2014 at 15:01

2 Answers 2

1

Looking into the setData function it appears that has data changes is always set to true even if technically the data has not changes.

This can be seen in Varien_Object function setData

public function setData($key, $value=null)
{
    $this->_hasDataChanges = true;
    if(is_array($key)) {
        $this->_data = $key;
        $this->_addFullNames();
    } else {
        $this->_data[$key] = $value;
        if (isset($this->_syncFieldsMap[$key])) {
            $fullFieldName = $this->_syncFieldsMap[$key];
            $this->_data[$fullFieldName] = $value;
        }
    }
    return $this;
}
1
  • Didn't you mean to say it's always true only for objects that have had their setData method called? Or am I mistaken? Commented Aug 9, 2017 at 15:26
0

Most of the times, I'm using the following code to check if a model changed:

$changed = $model->__toArray(array_keys($model->getOrigData())) != $model->getOrigData();

However, you'll need something else if you're going to check the product/category model after saving (for example from admin panel) or any other complex model. The problem there is that many values and types are different in $model->getData() vs $model->getOrigData().

Both product and category model have the updated_at field already updated. Product has also the stock_item object. Category has the image field in getOrigData() as type string and in getData() after save as array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.