|
Потратил много времени на обнаружение неочевидной особенности поведения системы кэширования объектов, получаемых из базы с использованием встроенной системы ORM Kohana в случае, если в свойствах модели не указано явно название таблицы, ей соответствующей.
Если вы инициализируете значение $_table_name ORM-модели в ее конструкторе (как в примере ниже):
class Model_Foo extends ORM
{
protected $_db = 'default';
protected $_primary_key = 'id';
protected $_primary_val = 'name';
...
public function __construct($id = NULL)
{
$this->_table_name = 'foo_table';
...
parent::__construct($id);
}
...
}
%0D%0Aclass%20Model_Foo%20extends%20ORM%0D%0A%7B%0D%0Aprotected%20%24_db%20%3D%20%27default%27%3B%0D%0Aprotected%20%24_primary_key%20%3D%20%27id%27%3B%0D%0Aprotected%20%24_primary_val%20%3D%20%27name%27%3B%0D%0A...%0D%0Apublic%20function%20__construct%28%24id%20%3D%20NULL%29%0D%0A%7B%0D%0A%24this-%3E_table_name%20%3D%20%27foo_table%27%3B%0D%0A...%0D%0Aparent%3A%3A__construct%28%24id%29%3B%0D%0A%7D%0D%0A...%0D%0A%7D%0D%0A
, то при попытке загрузить закэшированные данные с помощью конструкции вида:
$foos = ORM::factory('foo')->cached(7200)->find_all();
%0D%0A%26nbsp%3B%20%26nbsp%3B%24foos%20%3D%20ORM%3A%3Afactory%28%27foo%27%29-%3Ecached%287200%29-%3Efind_all%28%29%3B%0D%0A
вы получите, увы, вовсе не закэшированный результат, а вполне себе актуальные данные (которые, конечно же, будут получены ценой запроса к БД, которого вы хотели избежать)
Такое поведение Kohana обусловлено тем, что при чтении объекта из кэша и его последующей корректной десериализации подгружается файл с описанием класса вашей модели Model_Foo, однако его конструктор не вызывается и, соответственно, имя таблицы не инициализируется. Так как поля таблицы в модели не описаны, Kohana пытается загрузить список полей из таблицы, соответствующей названию модели в множественном числе - для примера выше это `foos`. Если такой таблицы в базе данных не находится, то генерируется исключение, которое интерпретируется системой кэширования как признак поврежденого кэша и обрабатывается втихую - возвращая NULL вместо данных. В результате данные загружаются каждый раз из базы данных, несмотря на то, что присутствуют в кэше.
Таким образом, явное указание $_table_name необходимо в тех моделях, выборки для которых вы хотите хранить в кэше и успешно доставать оттуда же.
Хочу особенно отметить, что при загрузке и десериализации объекта из кэша Kohana для него не вызывается автоматически конструктор. Это необходимо учитывать и инициализировать свойства (которые при обычной загрузке устанавливаются в конструкторе) при обращении к методам загруженного из кэша объекта, если они (методы) эти свойства используют.
|