метод search() модели, как работает?

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
rkk
Сообщения: 40
Зарегистрирован: 2016.03.04, 19:33

метод search() модели, как работает?

Сообщение rkk »

Доброго времени суток всем.

С Yii я знаком не так давно, но система очень понравилась, хочу разобраться с ней.
Поэтому прошу заранее прощения, если подобная тема обсуждалась, подскажите где почитать.

У меня есть 2 вопроса.
Есть две таблицы, которые я в последствии соединил при помощи JOIN и результат вывел в grid, как это правильнее делать при помощи метода search() модели?

Код: Выделить всё

CREATE TABLE `crt_cartridges` (
    cartridge_id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
    order_id int(11) NOT NULL,
    printer_id int(11) NOT NULL,
    cartridge_name VARCHAR(64) NOT NULL,
    serial_number VARCHAR(64) DEFAULT NULL,
    cartridge_description VARCHAR(256) DEFAULT NULL,
    KEY `printer_id` (`printer_id`),
    KEY `order_id` (`order_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

и

CREATE TABLE `crt_printers` (
    printer_id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
    order_id int(11) NOT NULL,
    room_id int(11) NOT NULL,
    person_id int(11) DEFAULT NULL,
    printer_name VARCHAR(64) NOT NULL,
    serial_number VARCHAR(64) DEFAULT NULL,
    inventory_number VARCHAR(64) DEFAULT NULL,
    KEY `room_id` (`room_id`),
    KEY `order_id` (`order_id`),
    KEY `person_id` (`person_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
соответственно есть 2 модели для `crt_printers` - "Printers", на данный момент стандартная, созданная при помощи gii, а для `crt_cartridges` - "Cartridges" я немного изменил

/*file model/Cartridges.php*/

Код: Выделить всё

class Cartridges extends CActiveRecord
{
    public $params = array();
    public $room_id = null;
    public $printer_name;
....    
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('printer_id, cartridge_name', 'required'),
            array('order, printer_id', 'numerical', 'integerOnly'=>true),
            array('cartridge_name, serial_number', 'length', 'max'=>64),
            array('cartridge_description', 'length', 'max'=>256),
            // The following rule is used by search().
            // @todo Please remove those attributes that should not be searched.
            array('cartridge_id, order, printer_id, cartridge_name, serial_number, cartridge_description, printer_name', 'safe', 'on'=>'search'), // добавил printer_name, работы поиска.
        );
    }
...
    public function search()
    {
        // @todo Please modify the following code to remove attributes that should not be searched.

        $criteria=new CDbCriteria;

        $criteria->join  = ' LEFT OUTER JOIN `crt_printers` `printers` ON (`t`.`printer_id`=`printers`.`printer_id`)';

        $criteria->select  = 't.*, printers.printer_name AS printer_name';
        
        $criteria->compare('cartridge_id',$this->cartridge_id);
        $criteria->compare('order',$this->order);
        $criteria->compare('printer_id',$this->printer_id);
        $criteria->compare('cartridge_name',$this->cartridge_name,true);
        $criteria->compare('serial_number',$this->serial_number,true);
        $criteria->compare('cartridge_description',$this->cartridge_description,true);
        $criteria->addSearchCondition('printer_name', $this->printer_name, true);

        return new CActiveDataProvider($this, array(
            'criteria'=>$criteria,
            'sort' => array(
                'defaultOrder' => '`order` ASC',
                'attributes'=>array(
                    '*',
                    'printer_name'=>array(
                        'asc'=>'printer_name ASC',
                        'desc'=>'printer_name DESC',
                    ),
//                    'owner_last_name'=>array(
//                        'asc'=>'last_name ASC',
//                        'desc'=>'last_name DESC',
//                    ),
                ),
            ),
        ));
    }
...
}
/*file views/cartridges/admin.php*/

Код: Выделить всё

<?php $this->widget('zii.widgets.grid.CGridView', array(
    'id'=>'cartridges-grid',
    'ajaxUpdate'=>false,
    'dataProvider'=>$model->search(),
    'filter'=>$model,
    'columns'=>array(
        'cartridge_id',
        'printer_name',
        'cartridge_name',
        'serial_number',
        'cartridge_description',
        array(
            'class'=>'CButtonColumn',
        ),
    ),
)); ?>
В результате у меня grid в котором я могу искать и сортировать по полю 'printer_name' которое джоиниться из другой таблицы.

1) вопрос первый, как мне вызвать search() из другого контролера, с определенным параметром и получить результат?
Например мне нужно получить данные записи с 'cartridge_id=1'
/*file controllers.php*/

Код: Выделить всё

        $cartridge=Cartridges::model()->findByPk($cartridge_id);
        if($cartridge===null)
            throw new CHttpException(404,'The requested page does not exist.');
        
        $this->render('create',array(
            'model'=>$model,
            'cartridge'=>$cartridge,
        ));
/*file views.php*/

Код: Выделить всё

<?php 
$this->widget('zii.widgets.CDetailView', array(
    'data'=>$model,
    'attributes'=>array(
        'cartridge_id',
        'order',
        'printer_id',
        'printer_name',
        'cartridge_name',
        'serial_number',
        'cartridge_description',
    ),
)); 
?>
соответственно 'printer_name' пустое так как findByPk читает только таблицу crt_cartridges.
Можно так конечно
/*file model/Cartridges.php*/

Код: Выделить всё

    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
            'printers' => array(self::BELONGS_TO, 'Printers', 'printer_id'),
        );
    }
и
/*file views.php*/

Код: Выделить всё

<?php 
$this->widget('zii.widgets.CDetailView', array(
    'data'=>$model,
    'attributes'=>array(
        'cartridge_id',
        'order',
        'printer_id',
        'printers.printer_name',
        'cartridge_name',
        'serial_number',
        'cartridge_description',
    ),
)); 
?>
Но можно ли это сделать через вызов search()?

2) второй вопрос. В поиске grid можно задать только определенные значения, но как выполнить следующею задачу?
Нужно передать, на пример, следующее условие в search():

Код: Выделить всё

WHERE printer_name='Canon' AND (cartridge_name = 'HP' OR cartridge_name = 'Canon') AND (serial_number=null OR cartridge_description=null)
и полученный результат передать функции которая экспортирует его в Ecxel?
Или как разобрать CActiveDataProvider построчно?

Вообще можно ли это все сделать при помощи метода search()?

Всем спасибо. :)
Ответить