creating virtual fields on the fly in CakePHP

2020-02-01 05:46发布

I wish to create virtual fields on the fly.

My Order & Order Details are like...

//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
        ),
    );
}

The model relation is like this. I am creating virtual fields on the fly so that I can count number of items and their cost in order pagination. I know the weird way of requestAction. Is their any way other I can perform my task.

My tried code is

        $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'));

It ends me with the mysql not found column Unknown column 'OrderDetail.order_id' in 'field list'. I haven't put recursive or bind my model to find something else. Why this error is generated ? How can I achieve my aim.

2条回答
相关推荐>>
2楼-- · 2020-02-01 06:02

You can create virtual fields on the fly with cakephp using this :

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

Here full_name is virtual field on the fly which make user's full name using first name and last name.

查看更多
老娘就宠你
3楼-- · 2020-02-01 06:08

you can create virtual fields on the fly. Your syntax is correct but you can do also this way:

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

the problem here is that Order is in HasMany relationship with OrderDetail. CakePHP in this case doesn't join the tables but rather makes two queries, one for the Orders and one for the OrderDetail and then merge the recordsets.

what can you do?

you can paginate OrderDetail instead of Order, and group it by 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')
);
查看更多
登录 后发表回答