Automatic cache update on model save/delete

Hi,

I’m fairly new to yii, really enjoying the framework!

I’ve been figuring out a way to automatically update fragment caches when a model saves or deletes and I’d like to run it by more experienced yii developers.

Model

My idea is to have a new class CActiveRecordCached that inherits from CActiveRecord. In this new class I override afterSave() and afterDelete() which will create a list of related models and update global state variables for each model e.g. for Post model, a global state variable called Cache.post will be updated with the timestamp. In addition, because Author is a related model, Cache.author will also be updated.

Any models which should trigger a fragment cache refresh should inherit from CActiveRecordCached.




class CActiveRecordCached extends CActiveRecord

{

	protected function afterSave()

	{

		parent::afterSave();

		$this->updateCacheDependencies();	

	}


	protected function afterDelete()

	{

		parent::afterDelete();

		$this->updateCacheDependencies();

	}


	protected function updateCacheDependencies()

	{

		//Update timestamps on related models so that view caches get updated

		$cacheUpdates = array();

		$cacheUpdates[] = 'Cache.'.$this->tablename();

		$relations = $this->relations();

		foreach($relations as $relation)

			$cacheUpdates[] = 'Cache.'.strtolower($relation[1]);


		foreach($cacheUpdates as $cacheUpdate)

		{

			Yii::app()->setGlobalState($cacheUpdate, time());

			Yii::app()->saveGlobalState();

		}

	}

}



View

Use fragment caches as usual, using CGlobalStateCacheDependency and using the appropriate global state variable e.g. Cache.post


<?php

	if($this->beginCache('postindex', array('dependency'=>array(

					'class'=>'system.caching.dependencies.CGlobalStateCacheDependency',

					'stateName'=>'Cache.post')))) { ?>

	//e.g. output post+author info



Therefore in the above example, if a post or author is updated/deleted, global states Cache.post and Cache.author are updated, causing any fragment caches with a dependency on either of these global states to refresh.

How does this sound?

Thanks,

Peter

Interesting approach. But I’d rather write a behaviour instead of extending CActiveRecord.

Thanks - yes, it makes more sense to use a behaviour - I’ll give it a go.