22
Yii ActiveRecord и подзапрос (subquery)
Программирование
Я довольно таки давно пишу на языке программирования php и использую framework Yii. В некоторых частях админки требуется иногда использовать подзапросы. И именно совместно с ActiveRecord.
Например во view/name-controller/admin.php. Мне потребовалось выводить все страницы (материалы) сайта и проверять какие из них прикреплены к пунктам меню сайта, а какие нет. Сразу объясню, что страницы (материалы) – это не статьи, а простые материалы по типу “О нас”, “Партнеры”, “Контакты”. То есть их на сайте будет не много и такой подзапрос не будет сильно ущемлять производительность админки и нагружать сервер. Хотя конечно же мою задачу можно было бы решить и по другому. Можно было бы например после прикрепления материала к пункту меню устанавливать в таблице этого материала какое-то поле, отвечающее за прикрепление к меню, в активное положение ну или инкрементировать это поле на единицу, так как один и тот же материал может быть прикреплен к разным пунктам меню, а при отсоединении материала от пункта меню уменьшать это моле на единицу. Тем самым, если значение поля “0″, то значит оно не прикреплено ни к одному пункту меню. Ну в общем я взял первую ситуацию просто для примера.
Итак у нас есть модель Material и контроллер MaterialController
Есть также файл вида view/material/admin.php и в этом файле вида мы хотим вывести только лишь материалы которых нет в меню, ну или есть. Например добавим в get параметры еще один (type, с возможными значениями menu, nomenu), который будет отвечать за то какие материалы показывать.
В модели у нас есть метод search
$criteria=new CDbCriteria; $criteria->compare('id',$this->id); $criteria->compare('title',$this->title,true); $criteria->compare('long_description',$this->long_description,true); $criteria->compare('active',$this->active); $operator = '>'; if(Yii::app()->getRequest()->getParam('type') == 'nomenu'){ $operator = '='; } $criteria->compare('(SELECT count(attach) FROM menu_items WHERE attach=CONCAT("material/", t.id))', $operator.'0', false, 'AND', false); $criteria->order = 'sort ASC'; return new CActiveDataProvider($this, array( 'criteria'=>$criteria, 'pagination' => array( 'pageSize' => Yii::app()->params->pageSize, ), )); |
Вот в этой строке
$criteria->compare(‘(SELECT count(attach) FROM menu_items WHERE attach=CONCAT(“material/”, t.id))’, $operator.’0′, false, ‘AND’, false);
видно как я создал подзапрос к таблице меню menu_items. Если вы программируете на php то по коду сами все поймете, поэтому я не расписывал все строки подробно. Будут вопросы, отвечу на них в комментариях.
На этом все. Удачи!