fuel / orm

Fuel PHP Framework - Fuel v1.x ORM
http://fuelphp.com/docs/packages/orm/intro.html
151 stars 95 forks source link

get_diff method does not work in event after_update of observer (fuel/orm version 1.8.0.1) #412

Closed huuphuc2401 closed 7 years ago

huuphuc2401 commented 7 years ago

I have Model_Product with property name

I add an observer Observer_Name to check name changed to model Model_Product

// fuel/app/classes/model/product.php
class Model_Product extends \Orm\Model
{
    protected static $_table_name = 'product';
    protected static $_properties = array(
        'id',
        'name',
        'price',
        'created_at',
        'updated_at',
    );
    protected static $_observers = array(
        'Orm\Observer_CreatedAt' => array(
            'events'          => array('before_insert'),
            'mysql_timestamp' => false,
        ),
        'Orm\Observer_UpdatedAt' => array(
            'events'          => array('before_update'),
            'mysql_timestamp' => false,
        ),
        '\\Observer_Name' => array('events' => array('after_update')),
    );
}
// fuel/app/classes/observer/name.php
class Observer_Name extends \Orm\Observer
{
    public function after_update(\Orm\Model $model)
    {
        var_dump($model->get_diff());
    }
}

Update name

$product = Model_Product::find(1);
$product->name = 'new name';
$product->save();

Expected result

var_dump display the diff of new name and old name

Result

var_dump display 2 empty arrays

More information

WanWizard commented 7 years ago

Thanks for reporting this. I can confirm this is still an issue with 1.9/develop.

WanWizard commented 7 years ago

Looked at the logic.

This behaviour is correct. The "after_update" observer is called AFTER the update has been completely processed. At this point, the object isn't in altered state anymore, it's state refects the data in the database, so there is no diff between the data in the object, and the data in the database.

Want you need is the "before_save" event, which gives you the state of the object before any save operation is executed, including any observers. You can also use "before_update", but that also gives you any changes made by observers (such as CreatedAt/UpdatedAt, depending on the order the observers are defined in).

The change made in 1.8.0.1 was a bug fix, to correct incorrect behaviour in previous versions.