Особенности межплагинного взаимодействия

Конечно, вызывать методы классов плагина из другого плагина не очень хорошо. Но, тем не менее. Чтобы впоследствии не было мучительно больно, при объявлении связей между моделями, надо всегда указывать свойство className, причем полностью, т.е. ‘Plugin.MyModel’. Иначе возможны весьма забавные эффекты. Справедливо для версий 1.2 и 1.3. Дальше немного кода.

Читать далее Особенности межплагинного взаимодействия

Производительность pagination в CakePHP 1.2

Хотя использование разбивки на страницы (pagination) вполне заслуживает отдельного, обстоятельного поста, хочу остановиться лишь на паре не слишком очевидных моментов. Я предполагаю, что у читающих этот пост есть определенный навык использования CakePHP, моделей вообще и pagination в частности. Этот пост и так получается длинным.

Известно, что метод контроллера paginate() вызывает последовательно два метода модели — первый для подсчета общего числа записей, удовлетворяющих заданным условиям, и второй на выборку указанного числа записей начиная с заданной. Т.е. первый это фактически функция SQL COUNT(*), второй — SELECT … LIMIT n,m.

Именно из-за того, что вызовов методов больше одного, не срабаывает временная привязка/отвязка подчиненных моделей с помощью bindModel()/unbindModel(). Этим методам, для корректной работы с paginate() приходится передавать второй параметр, равный false. К счастью, еть ContainableBehavior, решающий эту проблему.

Эти запросы не всегда оптимальны и есть возможность улучшить производительность метода paginate() именно за счет оптимизации собственно самих запросов. Читать далее Производительность pagination в CakePHP 1.2

Добавляем правила проверки данных на лету

Все в общем-то, тривиально и не стоило бы, наверное, пост городить. Но рассматривая код некоторых проектов на CakePHP я обнаружил удивительную вещь — во многих случаях данные формы проверяются не встроенным валидатором, а специально написанным кодом. Зачем? Непонятно.

Во-первых правила проверки — это просто ассоциативный массив, в который вполне можно добавлять элементы, прямо из метода контроллера. Никуда они при инициализации модели, не парсятся и не обрабатываются, пока не будет вызван валидатор.

Во-вторых валидатор отлично справляется с полями формы, которым нет соответствия в модели. А метод модели save() записывает только те поля, которым соответствуют колонки в таблице.

Вот, например, простая форма регистрации пользователя. Читать далее Добавляем правила проверки данных на лету

SluggableBehavior — помощник в создании ЧПУ

После выхода стабильной версии CakePHP количество постов в разных блогах, посвященных этому фреймворку, сократилось. Даже в Bakery тишина. Либо Рождество с Новым годом, либо все, засучив рукава, занялись разработкой.

В помощь неутомимым пекарям я решил рассказать об удобном расширении модели (behavior). Вещь, на мой взгляд, полезная. Работает отлично, я этим behavior пользуюсь уже почти год. Он помогает автоматически, при записи, сгенерировать slug для строки таблицы.

Вот, кстати, мне всегда было интересно, как правильно перевести на русский слово slug в этом контексте. Ярлык?

Этот behavior написал Mariano Iglesias. Это часть его проекта Cake Syrup. О другой интересной составляющей, SoftDeletableBehavior, недавно, кстати, можно прочесть здесь.

Это расширение не использует Inflector::slug() — когда оно создавалось, этого метода еще не было. Зато поддержка транслита русских букв в UTF-8 уже встроена, не без помощи Вашего покорного слуги. ;-) Читать далее SluggableBehavior — помощник в создании ЧПУ

M — for model

Очень-очень редко, но бывает нужно использовать в каком-нибудь методе контроллера несколько несвязанных между собой моделей. Еще раз, ключевые слова: «редко-редко» и «несвязанных».

Можно такие модели перечислить в переменной класса $uses — тогда, они, правда, будут загружаться для любого метода контроллера.

В версии 1.1 фреймворка была функция loadModel(), которая теперь отменена.

Есть еще метод requestAction(), но он объявлен «плохим». И правда, это, по сути, еще один запрос к приложению по полной программе, с диспетчеризацией, роутингом, стартом и инициализацией всех сопутствующих классов. В общем, путь неоптимальный и пользоваться им можно лишь от полной безысходности.

Можно воспользоваться методом App::import() — это хороший метод для многих классов. Но загруженная модель будет неполной. Т.е. это будет просто загруженный класс модели, без всех предварительных инициализаций самой модели и т.п. Этим методом лучше пользоваться для подгрузки своих классов или библиотек сторонних разработчиков.

В общем, я лично чаще всего в Cake 1.2 использовал именно App::import(), мирясь с некоторыми ограничениями. Но, оказывается есть еще один метод, позволяющий полностью загрузить модель, со всем ее «обвесом»

Читать далее M — for model

Многие ко многим — опасные связи

На этой неделе обновил CakePHP из SVN и тут же перестало работать добавление связей «многие-ко-многим» (hasAndBelongsToMany, HABTM). Небольшое расследование, сравнение изменений в коде и вопросы в гугл группе дали неутешительные результаты.

Во-первых у меня сложилось впечатление, что разработчики, несмотря на статус ReleaseCandidate (RC3) все еще не пришли к единому мнению относительно структуры данных, которую надо скармливать методу save(). :-/

Во-вторых естественные ключи в CakePHP практически «вне закона». Вот непонятно мне это — чем с точки зрения методов find(), save() и др. так сильно отличаются естественные ключи от синтетических? Тем более, что нечисловые первичные ключи все-таки поддерживаются. Это я про поля с UUID.

Проанализировав ситуацию, пришел к выводу, что на жанном этапе отказываться от естественных ключей пока неразумно и надо, видимо, добавлять такие связи самостоятельно. Тем более, что выборка по прежнему работает отлично. Т.е. нужно только реализовать добавление и удаление связей. Читать далее Многие ко многим — опасные связи