Yii 1.1: attributesbackupbehavior

A Yii ActiveRecord behavior to keep a backup of the loaded values for an ActiveRecord instance
26 followers

Introduction

Sometimes, when using ActiveRecord, we need to know if some attribute value has changed after it was loaded from the database. To make things easier and avoid duplicated code, I created this behavior to help me with this task. Basically, what it does is to make a copy of all attributes values from the object, right after it is loaded from the database, so the behavior can work with this original values to know if any of them was changed.

Usage

The behavior usage is pretty simple. First, add the behavior to the ActiveRecord where you intend to use it:

<?php 
class User extends ActiveRecord {
    ...
    public function behaviors() {
        return array(
            'AttributesBackupBehavior' => 'ext.AttributesBackupBehavior',
        );
    }
    ...
}
?>

After this, 3 new methods will be added to your User class: attributesChanged(), attributeChanged() and getOldAttributeValue().

Below is a description of it:

attributesChanged()

With this method you can check if any of the object attributes was changed after it was loaded from the database:

<?php
$user = User::model()->find(); // User->status == 'Active'
var_dump($user->attributesChanged()); // FALSE
$user->status = 'Inactive';
var_dump($user->attributesChanged()); // TRUE
?>

attributeChanged()

This should be used when you want to know if a specific attribute value was changed:

<?php
$user = User::model()->find(); // User->status == 'Active'
$user->status = 'Inactive';
var_dump($user->attributeChanged('email')); // FALSE
var_dump($user->attributeChanged('status')); // TRUE
?>

getOldAttributeValue()

In case you need to retrieve the original value loaded from the database, this is the method you gonna use:

<?php
$user = User::model()->find(); // User->status == 'Active'
$user->status = 'Inactive';
var_dump($user->getOldAttributeValue('status')); // 'Active'
?>

Besides those three methods, there's also one property that can be configured in this behavior: $reloadAfterSave.

By default, after you call the ActiveRecord save method, the old attributes will be erased and filled with the just saved new ones, show it will reflect the stored record. If for some reason you want to keep the original loaded values, you need to set $reloadAfterSave as false:

<?php 
class User extends ActiveRecord {
    ...
    public function behaviors() {
        return array(
            'AttributesBackupBehavior' => array(
                'class' => 'ext.AttributesBackupBehavior',
                'reloadAfterSave' => false,
        );
    }
    ...
}
?>

Changelog

1/13/2012 - Version 1.1 released fixing some typos and bugs and removing some unecessary code.

Resources

Total 10 comments

#14876 report it
Herode at 2013/09/17 11:32am
very convenient

Thanks !

#9692 report it
BerndBrot at 2012/09/03 08:29pm
LazySaferBehavior

I extended AttributesBackupBehavior to get LazySaferBehavior, which prevents its owner's save() command from being executed if no attributes have changed. It's available as a gist:

https://gist.github.com/3615263

#7331 report it
davi_alexandre at 2012/03/14 11:45am
@JFReyes

Yes, it does. Just remeber to call parent::afterFind() inside the afterFind() method of your class.

#7313 report it
JFReyes at 2012/03/13 11:33am
I need to use afterFind()

The extension looks interesting but I have encrypted data that must be decrypted before use and I do it in afterFind(). Does this extension support such usage? Thanks.

#6481 report it
davi_alexandre at 2012/01/12 10:04pm
@wisp

that is not the purpose of this extension

#6480 report it
davi_alexandre at 2012/01/12 10:03pm
@wiseon3

typo fixed, thanks for reporting!

#6471 report it
wisp at 2012/01/12 09:07am
extension

If you just want to make sure you're working with the latest data, you could also use refresh()

#6465 report it
redguy at 2012/01/12 07:32am
nice

In fact I wrote my own behavior like that, but it is really useful extension :)

#6462 report it
Wiseon3 at 2012/01/12 06:02am
Typo

There's a typo at line 42:

$this->old_attribtues

should be

$this->oldAttributes
#6461 report it
Junior - df9 at 2012/01/12 05:14am
Great

Very good and useful extension!

I was searching for something like this

:)

Thanks a lot

Leave a comment

Please to leave your comment.

Create extension