0

CakePHP がすべての関連付けを 1 つの SQL クエリに含めないのはなぜですか? これを行うことができた唯一の方法は「結合」を使用することですが、belongsTo と Containable の動作で十分であることを望みました。

以下に例を示します: Post->belongsTo->Category->belongsTo->category_type (すべてのモデルが正しくセットアップされ、動作します。

インデックスにページネーションを含む投稿をリストする、私はこれを試します:

public function index() {   
    $this->paginate = array( 'contain' => array('Category' => array('CategoryType')));
    $this->set('posts', $this->paginate());
}

これは配列を正しくフェッチしますが、次のような多くの SQL でそれを行います。

SELECT `Post`.`id`, `Post`.`name`, `Post`.`content`, `Post`.`category_id`, `Category`.`id`, `Category`.`name`, `Category`.`category_type_id` FROM `unit_app`.`post` AS `Post` LEFT JOIN `unit_app`.`categories` AS `Category` ON (`Post`.`category_id` = `Category`.`id`) WHERE 1 = 1 LIMIT 20
SELECT `CategoryType`.`id`, `CategoryType`.`name` FROM `unit_app`.`category_types` AS `CategoryType` WHERE `CategoryType`.`id` = 1
SELECT `CategoryType`.`id`, `CategoryType`.`name` FROM `unit_app`.`category_types` AS `CategoryType` WHERE `CategoryType`.`id` = 2
SELECT `CategoryType`.`id`, `CategoryType`.`name` FROM `unit_app`.`category_types` AS `CategoryType` WHERE `CategoryType`.`id` = 2

これにより、このクエリを CategoryType.name ASC で並べ替えることが難しくなります。助言がありますか?

結合が唯一のオプションである場合、クエリを実行する前にモデルのバインドを解除する必要がありますか? ページネーションは結合でうまく機能しますか?

ノート!これはすべてのモデルのほんの一部です。結果の post->index は、同様の関連付けを通じて他の多くのモデルをフェッチする必要があります。

(cake 2.2.0 および v2.4.0-dev、php v5.4.11 でテスト済み)

アップデート!----------

私は自分の発見を示したかっただけです。結合なしでこれを解決しましたが、モデルを再バインドして機能させる必要がありました。

これは基本的に私がそれを機能させるために行ったことです(ページネーションとソートも):Postモデルでは:バインド機能を追加しました:

  $this->unbindModel(array(
    'belongsTo' => array('Category')
  ));

  $this->bindModel(array(
    'hasOne' => array(
      'Category' => array(
        'foreignKey' => false,
        'conditions' => array('Category.id = Post.category_id')
    ),
    'CategoryType' => array(
      'foreignKey' => false,
      'conditions' => array('CategoryType.id = Category.category_type_id')
    ))));

次に、これを Post コントローラーのインデックスに追加しました。

  $this->Post->bindCategory();
  $this->paginate = array('contain' => array('Category' ,'CategoryType'));
  $this->set('posts', $this->paginate());

ドキュメント用にテーブルヘッダーも含めます。

<th><?php echo $this->Paginator->sort('CategoryType.name', 'Type'); ?></th>
<th><?php echo $this->Paginator->sort('Category.name', 'Category'); ?></th>

この投稿が他の人にも役立つことを願っています:)

また、この動作をテストして、バインド関数もすべて省略できるかどうかを確認します: https://github.com/siran/linkable/

Cake にはたくさんのプラグインがありますが、cake にはプラグインの「認証」が必要です。完全に機能し、テスト済みのものを github で見つけるのは非常に困難です :)

また、ケーキのためだけに railscasts.com のようなサイトが恋しいです :D

/マートン

4

1 に答える 1

0

はい、関連するモデルの結果に基づいて注文できるようにするには、JOINを使用する必要があります。

はい、JOINを使用してページ分割できます。実際にを呼び出す前に、オプション(JOINを含む)をページネーションに渡すだけ$this->paginate();です。(JOINでページ付けする方法についてはオンラインで多くのリソースがあります)

于 2013-03-13T17:48:45.857 に答える