I have a few many-to-many relationships that I would like to cache.
Is there a way to override the function that generates the query to check for a cache key first? (Then set/get as needed).
Thanks!
|
Sep '18 |
6 |
1206 |
0 |
Here's how I'm accessing the relation:
$this->hasManyToMany(
'user_id',
'\NS\UserRole',
'user_id', 'role_id',
'\NS\Role',
'role_id',
array('alias'=>'roles')
);
$user = User::findFirst();
$roles = $user->roles; // This is what I want to cache
Of course, this is just one example, I have several classes that use relations like this, so if I could write a generic caching function/class, that'd be great.
There are two methods in Phalcon Mvc Model that handle related rows in model relations as below:
/**
* Returns related records based on defined relations
*
* @param string alias
* @param array arguments
* @return \Phalcon\Mvc\Model\ResultsetInterface
*/
public function getRelated($alias, $arguments=null){ }
/**
* Returns related records defined relations depending on the method name
*
* @param string modelName
* @param string method
* @param array arguments
* @return mixed
*/
protected function _getRelatedRecords($modelName, $method, $arguments){ }
You should make your own Model for example App\Model\AbstractModel.php that overrided these methods and you should extend other models from these abstract model too. your methods could be something like this:
namesapce App\Model
class AbstractModel extends \Phalcon\Mvc\Model
{
/*
* Returns related records based on defined relations
*
* @param string alias
* @param array arguments
* @return \Phalcon\Mvc\Model\ResultsetInterface
*/
public function getRelated($alias, $arguments=null){
$rows = $this->cache->get("{$alis}CacheKey");
if ($rows === null) {
$rows = parent::getRelated($alias, $arguments);
$this->cache->save("{$alis}CacheKey", $rows);
}
return $rows
}
// EXTEND ANY METHOD ....
}
Ok, one final question -- I've overridden the getRelated($alias, $arguments = NULL) function.
Here's what I've got:
// This works great.
$roles = $user->getRelated('roles').
// this does not (the data gets populated correctly, but doesn't run the new function)
$roles = $user->roles
However, when I run $roles = $user->roles, my user defined function does not run, so must be another function that runs when accessing a relationship directly via alias. It's not a terribly big deal, but I think $user->roles looks nicer and reads more easily.
I don't know exactly which function is responsible for relation handling but its better to check Phalcon Mvc Model class and find the correct method.
Check this link
:
https://github.com/phalcon/phalcon-devtools/blob/master/ide/2.0.0/Phalcon/Mvc/Model.php
No -- it's not a terribly big effort to do as you suggested. However, the software I'm writing may or may not have access to memcache, it'll be a config option. So overriding a method in the model itself means I only have to check the config in one place, rather than all the different places I would call $user->getRelated() or $user->getRoles().
i know its outdated
but for the sake of someone looking for answer ( many to many cache )
i wrote a class that should auto cache your models
whether you do Robots::find()
or $robots->robotParts
or $robot->getRobotParts()
etc
you can check it out at this gist
hope this helps