Since I'm using Phalcon I'm having lot of problems with cached relationships and the lazy loading. Actually I'm triying to fetch a model and get the relationships, but I want the relationships from the cache. I already read the Caching in the ORM documentation, but I don't like the approach, since it implies caching on the ' find' methods...
The use case:
* call a public property alias for the relationship
* If the alias have results, get them
* if the alias does not have results, try to get them from cache
* if no cache, fetch them
I extended the Phalcon Model to use the cache on the relationships, in this way:
/*
* Returns related records based on defined relations USING CACHE
*
* @param string alias
* @param array arguments
* @param int ttl in seconds
* @return \Phalcon\Mvc\Model\ResultsetInterface
*/
public function getRelated($alias, $arguments = null, $ttl = null)
{
$cache_ttl = ($ttl !== null) ? $ttl : (isset(static::$cache_ttl)) ? static::$cache_ttl : self::$cache_ttl_default;
$cache_key = $this->getSource() . '.' . $this->getId() . '.' . $alias . '.' . md5(serialize($arguments));
$rows = $this->getDI()->getCache()->remember($cache_key, $cache_ttl, function () use ($alias, $arguments) {
return parent::getRelated($alias, $arguments);
});
return $rows;
}
// remember is just a get if exists and if not, execute callback and save it
The problem with this approach is that I must define getters and call getRelated
on them.
The second problem is that every time I call those getters the results are fetched from the cache or the lazy loading, never from the already fetched ones. This means that I must control when I need to call $model->getAliasRelationship()
so cache-lazyloading is used, or call $model->aliasRelationship
so the already fetched ones are used.
Due to the lazyloading I cannot check if the property is already filled without firing the "automagic" fetch. If I do it I lost the posibility to use the cache.
https://github.com/phalcon/cphalcon/pull/12772 points there. With a method to check if the relationship is already fetched, without fetching it if not, is just as easy as adding the check on the overrided getRelated
.
I was looking for a way to redefine the __get
so I can avoid the automatic lazyloading and make my own checks on cache etc... and found that those three methods getRelated, _getRelatedRecords, __get
make use of the modelManager
and I can't find a way to make it more transparent.
As I see it, it would be great that those methods getRelated, _getRelatedRecords, __get
make use of a common method to fetch relationships (a proxy for the modelManager) so I can override it and not necesarily be suscribed to this handicap.
Any clue on how to accomplish it?