0

私は自分の PhotosController.php のビュー アクションにいます。私がやりたいことは、私が見ている現在の写真のIDを指定して、現在の写真の前の2枚の写真と現在の写真の後の2枚の写真を含む写真のカルーセルを作成し、現在の写真を中央に配置することです(合計5枚)。

私はこの解決策を指摘されましたが、$this->Photo->query を使用して CakePHP に変換できないようです。

私のコントローラー

$this->set('photos', $this->Photo->query("
    SELECT id, file FROM photos WHERE id <= $id AND page_id = $page_id ORDER BY id DESC LIMIT 3 
    UNION ALL
    SELECT id, file FROM photos WHERE id > $id AND page_id = $page_id ORDER BY id ASC LIMIT 2
"));

残念ながら、デバッグをオンにしても何も表示されません。id、file、および page_id はすべて photos テーブルの列です。#id と $page_id の両方がルーターからアクションに渡されます。私の構文は間違っていますか?

編集: UNION ALL と 2 番目の SELECT ステートメントを削除すると、クエリは正常に機能するため、モデルがロードされないという問題はありません。

編集 (回避策):今のところ、理想的ではない 2 つのクエリを実行しています。

$this->set('photos_before', $this->Photo->find('all', array(
    'conditions' => array(
        'Photo.page_id' => $page_id,
        'Photo.id <' => $id
    ),
    'order' => array('Photo.id ASC'),
    'limit' => 2
)));

$this->set('photos_after', $this->Photo->find('all', array(
    'conditions' => array(
        'Photo.page_id' => $page_id,
        'Photo.id >' => $id
    ),
    'order' => array('Photo.id ASC'),
    'limit' => 2
)));

必要なフィールドと関連するモデルのみを返すために、事前にコンテインを用意しています。

以下は私が表示したいもので、現在は上記の 2 つのクエリを使用して動作しますが、1 つの Cake に適したクエリでこれを実現できることを願っています

これは私が表示したいもので、現在は上記の 2 つのクエリを使用して動作しますが、1 つの Cake に適したクエリでこれを実現できることを願っています

4

3 に答える 3

2

私の推測では、元のクエリは無効な SQL です。Afaik UNIONS には、複数の「order by」句を含めることはできません。回避策として、次のようなサブクエリを使用するように書き直すことを検討してください。

SELECT * FROM (SELECT id, file FROM photos WHERE id <= $id AND page_id = $page_id ORDER BY id DESC LIMIT 3) AS suba
UNION ALL
SELECT * FROM (SELECT id, file FROM photos WHERE id > $id AND page_id = $page_id ORDER BY id ASC LIMIT 2) AS subb

私は真剣に考えていますが、このようなクエリは最適とはほど遠いものです。もちろん、あなたのアプリケーションがどのように機能するかはわかりませんが、OFFSET/LIMIT を使用した標準のページネーション クエリがより論理的なアプローチのようです。

あなたの質問の下にある私のコメントを考慮に入れてください。model->query を使用しても、SQL インジェクションを防ぐためにサニタイズ/エスケープが自動的に処理されるわけではありません!

于 2013-02-22T21:16:23.180 に答える
0

モデルを次のようにロードする必要があります

  $this->loadModel('Photo');

クエリ実行前。

于 2013-02-22T14:29:34.210 に答える