4

私はこのようなモデル関係を持っています:

ProjecthasManyhasMany SubProject_Item

特定の に属するcontainableすべての を検索できるように配列を設定し、結果をページ付けしたいと考えています。だから、私の中には:ItemProjectItemsController

public $paginate = array(
  'Item' => array(
    'limit' => 10,
    'order' => array('
      'Item.create_time' => 'desc'
    ),
    'contain' => array(
      'SubProject' => array(
        'Project'
      )
    )
  )
);

明らかに、どこかに のような条件を配置する必要がありますが"SubProject.project_id = $pid"、私が試したものは何も正しい結果をもたらしません。私が管理できる最善の結果は、次のようなものです。

Array
(
[0] => Array
    (
        [Item] => Array
            (
                [id] => 13
                [file_name] => foo.tar.gz
                .... other keys ...
                [create_time] => 2013-01-23 14:59:49
                [subProject_id] => 4
            )

        [SubProject] => Array
            (
                [id] => 4
                [name] => foo
                [project_id] => 2
                ..... other keys ....
                [Project] => Array
                    (
                    )

            )

    )
 [1] => Array
 .....

編集:一致しないプロジェクトレコードを正確に省略しています。一致するプロジェクト レコードがないアイテム レコードをスキップしたい。

joins を手動で指定することは私の頭をよぎりましたが、それは必要ではないと感じています。

これは明らかなように思えますが、残念ながら、解決策は私にはわかりません。

4

2 に答える 2

9

私は最終的にこの問題を解決したので、他の人の助けになることを期待して、私がしたことを説明したいと思いました.

Mark Story によるこのブログ投稿(1.2 の時代のものですが、まだ関連性があります) を読んだ後、Project モデルを直接バインドするカスタム検索タイプを Item モデルに作成することにしました。これにより、Containable が正しくフィルタリングできる第 1 レベルの関連付けが得られます。

したがって、Items モデルには次のようなものがあります (カスタム検索タイプのドキュメントを参照してください)。

public $findMethods = array('byProject' => true);

public function _findByProject($state, $query, $results=array()) {
    if ($state == 'before') {
        $this->bindModel(array(
            'hasOne' => array(
                'Project' => array(
                    'foreignKey' => false,
                    'conditions' => array('Project.id = SubProject.project_id')
                )
            )
        ));
        return $query;
    }
    return $results;
}

foreignKeyCakePHP が存在しないデータベースキーを自動的に使用しようとするのを防ぐために、 falseに設定する必要があることに注意してください。ItemsController では、ページネーション オプションは次のようになります。

public $paginate = array(
    'Item' => array(
        'findType' => 'byProject',
        'limit' => 10,
        'order' => array(
            'Item.create_time' => 'desc'
        ),
        'contain' => array(
            'SubProject',
            'Project'
        ),
        'conditions' => array('Project.id' = $pid)
    ),
);

...$pid表示するプロジェクトの ID です。わずかに異なる結果の配列構造に対応するために、ビューのコードを微調整し、すべて準備が整いました。

于 2013-01-26T23:30:04.637 に答える
1

編集 ===============

public $paginate = array(
    'limit' => 10,
    'order' => 'Item.create_time DESC',      //'order' => array(''Item.create_time' => 'desc'),
    'contain' => array(
        'SubProject' => array(
            'Project' => array(
                'conditions' => array(
                    'id' => $project_id    // Passed parameter
                )
            )
        )
     )
);

=================================================

次のように使用conditionsしてみましたか?また、コードの「注文」セクションをあなたのように書きませんでした。

public $paginate = array(
    'Item' => array(
        'limit' => 10,
        'order' => 'Item.create_time DESC',      //'order' => array(''Item.create_time' => 'desc'),
        'contain' => array(
            'SubProject' => array(
                'Project' => array(
                    'conditions' => array(
                        'id' => $project_id    // Passed parameter
                    )
                )
            )
        )
     )
);
于 2013-01-25T19:53:17.547 に答える