How To Update Created And Modified Dates In All Models?

Most, but not all, of my mysql tables have a created and modified DATETIME field. Currently I’m using the following Yii code to update them appropriately:


public function beforeSave()

{

    if ($this->isNewRecord) {

        $this->created = new CDbExpression('UTC_TIMESTAMP()');

    }

    else {

        $this->modified = new CDbExpression('UTC_TIMESTAMP()');

    }


    return parent::beforeSave();

}



This works but it has the disadvantage that I have to repeat the code in all models that have these fields. I’d like to reduce code repetition; what’s the best way to do that?

My first thought is create a custom base class derived from CActiveRecord that all my models will inherit and put the above "beforeSave" code in that custom base class. However, as I mentioned not every single model will have created,modified time stamps. Is there a way to test if a model has a given attribute?

You could also use a behavior:




class TimeLogBehavior extends CActiveRecordBehavior

{

    public function afterSave($event)

    {

        if ($this->getOwner()->isNewRecord)

            $this->getOwner()->created = new CDbExpression('UTC_TIMESTAMP()');

        else

            $this->getOwner()->modified = new CDbExpression('UTC_TIMESTAMP()');

    }

}



Then, in the classes where you want to use this functionality:




    public function behaviors()

    {

        return array(

            'TimeLogBehavior' => 'path.alias.to.TimeLogBehavior',

        };

    }



Alternatively, you could just configure the database table itself to monitor creation and modification times. In MySQL, set the created column’s default value to CURRENT_TIMESTAMP and the modified column to use the attribute ON UPDATE CURRENT_TIMESTAMP.

Thanks I was wondering about using behaviors. This still has the disadvantage that you have to specify the behavior in each class, although the advantage is it’s explicit and slightly less code. Maybe I will just stick with copy and pasting the beforeSave method into each model. I don’t have that many models right now.

I don’t think letting the database update columns will work with mysql using datetime type. I’m not interested in using TIMESTAMP as to me that is just a year 2038 problem waiting to happen. Can’t use triggers in my current environment.

@Keith there’s a CTimestampBehavior http://www.yiiframework.com/doc/api/1.1/CTimestampBehavior

You can also extend CActiveRecord and add the behavior to it and have your models extend that class.

Funny finally found someone trying to what I was trying to do with the attribute check:

[solved] any way to check if a column exists in an AR object?

I never stop learning about Yii’s features…

Nobody does ;) apart I guess core members :D

there is an interesting article on wiki about this

http://www.yiiframework.com/wiki/355/auto-set-model-fields-values/