Reputation: 501
In some model classes I want to implement cache. And I wanted to do that like:
UsersModel::model()->findByAttributes([...])
In that class I wanted to override method beforeFind()
to send request first to cache server, but it seems that method does not take any additional parameters, nor does have object with attributes.
Putting additional conditions/checks in top level code something like :
$response = Yii::app()->cache->get('userUserLogin');
if(empty($response) == true) {
//fetch data from db and set to cache
$userModel = UsersModel::model->findByAttributes([...])
Yii::app()->cache->set('user' . $userModel->username, $userModel->getAttributes());
}
is not nice and trivial, leading to many branches.
Upvotes: 0
Views: 163
Reputation: 22174
You should not use beforeFind()
for that. Besides technical problems in implementation, you may get many side effects and hard to debug bugs because of that. That is because cache may be out of date and many internal Yii logic may rely on assumption, that findByAttributes()
(and other methods) always fetches fresh data from database. You will also not be able to ignore cache and get model directly from database.
In general you have 2 options:
CActiveRecord::cache()
$model = UsersModel::model()->cache(60)->findByAttributes([...])
This will query cache results for 60 seconds.
You may add custom methods, which will simplify using cached active records:
public static function findByAttributesFromCache($attributes = []) {
$result = Yii::app()->cache->get(json_encode($attributes));
if ($result === false) {
//fetch data from db and set to cache
$result = static::model()->findByAttributes($attributes);
Yii::app()->cache->set(json_encode($attributes), $result, 60);
}
return $result;
}
You can add such method to trait and reuse it in multiple models. Then all you need is:
$userModel = UsersModel::findByAttributesFromCache([...]);
Upvotes: 1