создание виртуальных полей на лету в CakePHP

Я хочу создавать виртуальные поля на лету.

Мой заказ и детали заказа похожи на...

//Order Model
class Order extends AppModel {
    public $name = 'Order';
    public $actsAs = array('Containable');
    public $hasMany = array(
        'OrderDetail' => array(
            'className' => 'OrderDetail',
            'foreignKey' => 'order_id',
            'dependent' => true
        ),
    );
}

//OrderDetail Model
  class OrderDetail extends AppModel {
    public $name = 'OrderDetail';
    public $actsAs = array('Containable');
    public $belongsTo = array(
        'Order' => array(
            'className' => 'Order',
            'foreignKey' => 'order_id',
            'dependent' => true
        ),
    );
}

Отношение модели такое. Я создаю виртуальные поля на лету, чтобы я мог подсчитывать количество элементов и их стоимость в порядке разбивки на страницы. Я знаю странный способ requestAction. Я могу выполнить свою задачу любым другим способом.

Мой проверенный код

        $this->Order->virtualFields['totalCost'] = 0;
        $this->Order->virtualFields['totalItem'] = 0;
        $fields = array('Order.id', 'Order.order_key', 'Order.delivery_date','COUNT(`OrderDetail`.`order_id`) AS `Order__totalItem`', 'SUM(`OrderDetail`.`cost`) AS `Order__totalCost`');         

        $this->paginate['Order'] = array("fields"=>$fields, 'conditions' => array("AND" => array($condition, "Order.status" => 3)), 'limit' => '50', 'order' => array('Order.id' => 'DESC'));

Это заканчивается тем, что столбец mysql не найден Unknown column 'OrderDetail.order_id' in 'field list'. Я не ставил рекурсию и не привязывал свою модель, чтобы найти что-то еще. Почему генерируется эта ошибка? Как я могу достичь своей цели.


person Sankalp    schedule 10.10.2013    source источник
comment
Как я могу сделать это на Cakephp3? пожалуйста помоги?   -  person baur79    schedule 08.10.2017
comment
См. это для Cake3+ на уровне объекта. (не требуется SQL). Для SQL используйте задокументированные виртуальные поля как выражения SQL: book.cakephp.org/3/en/orm/ .   -  person mark    schedule 05.02.2020


Ответы (2)


вы можете создавать виртуальные поля на лету. Ваш синтаксис правильный, но вы можете сделать и так:

$this->Order->virtualFields['totalCost'] = 'SUM(`OrderDetail`.`cost`)';
$this->Order->virtualFields['totalItem'] = 'COUNT(`OrderDetail`.`order_id`)';

проблема здесь в том, что Order находится в отношениях HasMany с OrderDetail. CakePHP в этом случае не объединяет таблицы, а делает два запроса, один для Orders и один для OrderDetail, а затем объединяет наборы записей.

что ты можешь сделать?

вы можете разбить на страницы OrderDetail вместо Order и сгруппировать его по Order.id

$fields = array
(
    'Order.id', 
    'Order.order_key', 
    'Order.delivery_date', 
    'Order.totalItem', 
    'Order.totalCost'
);         

$this->paginate['OrderDetail'] = array
(
    "fields"=> $fields, 
    'conditions' => array("AND" => array($condition, "Order.status" => 3)), 
    'limit' => '50', 
    'order' => array('Order.id' => 'DESC'),
    'group' => array('Order.id')
);
person arilia    schedule 10.10.2013
comment
Заставить торт выполнить один запрос, используя 'joins' => array(...)? - person Fr0zenFyr; 02.02.2017

Вы можете создавать виртуальные поля на лету с cakephp, используя это:

class User extends AppModel {
    public $virtualFields = array(
            'full_name' => 'CONCAT(User.first_name, " ",User.last_name)'
        ); 
}

Здесь full_name — это виртуальное поле на лету, которое создает полное имя пользователя, используя имя и фамилию.

person Krishna Gupta    schedule 14.07.2015
comment
Это не на лету - person Berry M.; 04.07.2017