0

CakePhp 2.xアプリケーションのOrdersテーブルから結果のリストを取得して、今日に最も近い日付で並べ替えようとしています。

通常のmysqlクエリでは、次の構文を使用して同様の作業を行っています。

ABS(DATEDIFF(Order.duedate, NOW()))

ただし、Cakeでは、このようなカスタムクエリをpaginateヘルパー内で機能させる方法がわかりません。これは、モデルのファインダークエリで設定する必要があるものですか?

これが私が現在持っているコントローラーです(ボグ標準の降順ソートに設定されています)

    public function index() {
           $this->paginate = array( 
                    'conditions' => array (
                        'Order.despatched' => array('Not Despatched' , 'Split Despatched')
                    ),
                    'limit' => 25,
                    'order' => array('Order.duedate' => 'DESC')
            );

           $data = $this->paginate('Order');
           $this->set('orders', $data);
}

編集:以下のコメントの情報を使用して、SQLエラーの原因となる仮想フィールドをコントローラーに追加しました。最初は、これはモデル内の関連付けによるものだと思いました。これを修正するために、virtualFieldをOrderモデルと関連付けられたAccountModelのコンストラクターに追加しました。ただし、これによってSQLの破損部分は変更されませんでした。完全なSQLエラーは次のとおりです。

Error: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS `Order__closestdate`, `Account`.`id`, `Account`.`company`, `Account`.`contac' at line 1

SQL Query: SELECT `Order`.`id`, `Order`.`order_id`, `Order`.`orderdate`,
 `Order`.`duedate`, `Order`.`rework`, `Order`.`rework_notes`, `Order`.`comments`, 
`Order`.`status`, `Order`.`customer`, `Order`.`last_edited`, `Order`.`value`, 
`Order`.`quantity`, `Order`.`order_for`, `Order`.`warehouse`, `Order`.`haulier`, 
`Order`.`terms`, `Order`.`type`, `Order`.`despatched`, `Order`.`despatched_date`, 
`Order`.`invoiced`, `Order`.`invoice_date`, `Order`.`bookingref`, 
`Order`.`purchaseref`, `Order`.`payment_due`, `Order`.`payment_status`, 
`Order`.`payment_date`, (ABS(DATEDIFF(duedate, NOW())) AS `Order__closestdate`, 
`Account`.`id`, `Account`.`company`, `Account`.`contact`, `Account`.`phone`, 
`Account`.`email`, `Account`.`postcode`, `Account`.`created`, `Account`.`modified`, 
`Account`.`customer`, `Account`.`address1`, `Account`.`address2`, `Account`.`town`, 
`Account`.`county`, (ABS(DATEDIFF(duedate, NOW())) AS `Account__closestdate` FROM 
`hunter_om`.`orders` AS `Order` LEFT JOIN `hunter_om`.`accounts` AS `Account` ON 
(`Order`.`customer` = `Account`.`customer`) WHERE `Order`.`despatched` IN ('Not 
Despatched', 'Split Despatched') ORDER BY (ABS(DATEDIFF(duedate, NOW())) DESC LIMIT 25

参考までに、モデルのコードは次のとおりです。

//Order Model
public $virtualFields = array(
   'closestdate' => 'ABS(DATEDIFF(duedate, NOW())'
);

//Account Model
  public function __construct($id = false, $table = null, $ds = null) {
   parent::__construct($id, $table, $ds);
   $this->virtualFields['closestdate'] = $this->Order->virtualFields['closestdate'];
   }

どんな助けでもありがたいです。

4

1 に答える 1

2

ページネーションの前に Order モデルに「virtualField」を追加する必要があります。

$this->Order->virtualFields['closestdate'] = "ABS(DATEDIFF(Order.duedate, NOW()))";

次に、そのフィールドをクエリ/ページネーションの通常のフィールドとして使用します

public function index() {

    $this->Order->virtualFields['closestdate'] = "ABS(DATEDIFF(Order.duedate, NOW()))";

    $this->paginate = array( 
        'conditions' => array (
            'Order.despatched' => array('Not Despatched' , 'Split Despatched')
        ),
        'limit' => 25,
        'order' => array('Order.closestdate' => 'DESC')
    );

    $data = $this->paginate('Order');
    $this->set('orders', $data);
}
于 2013-02-03T15:24:26.600 に答える