cakephpでHABTMなアソシエーションが思うように動作しないので単純化テストする その3

実験準備

  • ページングに入るので果物に属するレコードを追加しておく
INSERT INTO `products` VALUES (9, 'バナナ', 0);
INSERT INTO `products` VALUES (10, 'びわ', 0);
INSERT INTO `products` VALUES (11, 'サクランボ', 0);
INSERT INTO `products` VALUES (12, 'オレンジ', 0);
INSERT INTO `products` VALUES (13, 'パイナップル', 0);
INSERT INTO `products` VALUES (14, '柿', 0);
INSERT INTO `products` VALUES (15, 'スイカ', 0);
INSERT INTO `products` VALUES (16, 'トウモロコシ', 0);
INSERT INTO `products` VALUES (17, '梨', 0);

INSERT INTO `categories_products` VALUES (9, 1);
INSERT INTO `categories_products` VALUES (10, 1);
INSERT INTO `categories_products` VALUES (11, 1);
INSERT INTO `categories_products` VALUES (12, 1);
INSERT INTO `categories_products` VALUES (13, 1);
INSERT INTO `categories_products` VALUES (14, 1);
INSERT INTO `categories_products` VALUES (15, 1);
INSERT INTO `categories_products` VALUES (16, 1);
INSERT INTO `categories_products` VALUES (17, 1);
  • テンプレに$paginatorを追記
    • ページングを使わずにビューにわたそうとするとデザインが崩れ白っぽくなる(cssを読まない=layoutsを通してない)
APP/views/products/index.tpl
{$form->create("Product", $view->aa('action','index'))}
{$form->select('Category.id',$category_list,$category_selected)}
{$form->end('検索')}
<br />

{$paginator->options($paginator_option)}
{$paginator->counter($view->aa('format',"全%count%件中%current%件を表示してます"))}<br />
{$paginator->prev('<<')}
{$paginator->numbers()}
{$paginator->next('>>')}

<table cellpadding="0" cellspacing="0">
<tr>
  <th>名前</th>
  <th>表示</th>
  <th>操作</th>
</tr>
{foreach from=$products item='product'}
  <tr>
    <td>
    {assign var='id' value= $product.Product.id}
    {$html->link($product.Product.name, "view/$id")}
    </td>
    <td>
    {$product.Product.hidden}
    </td>
    <td>
      {$html->link('編集', "/products/edit/$id")} 
      {$html->link('削除', "/products/delete/$id")}
    </td>
</tr>
{/foreach}
</table>

試行錯誤

  • 4パターン(だけじゃないけど)試してみた
  • (1)は前回の最終形にページングを適応したつもりなんだけどリレーションのproductテーブル情報が取れない
    • なんで取れないのかフォーラムに聞いてみようか?
    • 件数はあってるのでこれをもとにしていじっていく
  • (2)と(3)は同じ意味
    • Productモデルのhidden検索なら期待通りの動作
    • paginate()の第2引数に検索条件を入れてもok
    • $this->paginate['Product']['conditions']に検索条件を入れてもok
  • (4)Categoryモデルで検索すると1件ヒットしその下に複数件レコードがぶらさがるので適当でない
APP/controllers/products_controller.php(抜粋)
                //目的のレコードが出るけどProducts.nameが取れない(1)
                $this->Product->bindModel(array('hasOne' => array('CategoriesProduct')));//あってもなくても同じ=機能してない
                $products = $this->paginate('CategoriesProduct', array('CategoriesProduct.category_id' => 1));
                
                
                //Product.hiddenの条件検索はできる 表示も正常(2)
                $products = $this->paginate('Product', array('hidden' => 0));
                
                
                //Product.hiddenの条件検索はできる 表示も正常 プロパティの書き換えでも同じ(3)
                $this->paginate['Product']['conditions'] = array('hidden' => 0);
                $products = $this->paginate();
                
                //Category.idの条件検索はできるが、配列の形が違うので表示できない 結果は1件(4)
                $products = $this->paginate('Category', array('id' => 1));

ページングできるようにする

APP/controllers/products_controller.php
<?php
...
    function index() {
        
        if (!empty($this->data)) {
            //POST つまりフィルタの指定をした場合
            if($this->params['data']['Category']['id'] != ''){
                //カテゴリ指定がある場合
                
                //通常find()と同じような配列を無理やり作ってやった。おそらく、$paginator->sort()が機能しないだろう
                $products = $this->paginate('CategoriesProduct',
                    array('CategoriesProduct.category_id' => $this->params['data']['Category']['id']));
                foreach($products as $key => $value){
                    $product_id = $products[$key]['CategoriesProduct']['product_id'];
                    $product_data = $this->Product->read(null, $product_id);
                    $products[$key]['Product'] = $product_data['Product'];
                }
                $this->set('paginator_options', array('url' => array( 'category_id' => $this->params['data']['Category']['id'])));
                
            }else{
                //カテゴリ指定がない場合
                $products = $this->paginate();
            }
            
        }else{
            //GET 初アクセスかフィルタを継続する場合
            
            if($this->params['named']['category_id'] != ''){
                $products = $this->paginate('CategoriesProduct',
                    array('CategoriesProduct.category_id' => $this->params['named']['category_id']));
                foreach($products as $key => $value){
                    $product_id = $products[$key]['CategoriesProduct']['product_id'];
                    $product_data = $this->Product->read(null, $product_id);
                    $products[$key]['Product'] = $product_data['Product'];
                }
                $this->set('paginator_options', array('url' => array( 'category_id' => $this->params['named']['category_id'])));
                $this->set('category_selected',$this->params['named']['category_id']);
                
            }else{
                //カテゴリ指定がない場合
                $products = $this->paginate();
            }
        }
        
        pr($products);
        $this->set('products', $products);
        $this->set('category_list',$this->Category->find('list'));
        
        
    }
...
?>

$paginator->sort()がエラーする{$paginator->sort('名前','name')}と省略しないで書こう

  • 'Product.name'だけでなく'product_id'も'category_id'でも動かない
  • ちょっとお手上げ状態
フィルタなしで動いた設定
コントローラープロパティに追記
        'Product' => array(
            'limit'=> 5,
            'order'=> array(
                'id'=> 'asc')));
コントローラーindexメソッドに
        $this->Product->bindModel(array('hasOne' => array('CategoriesProduct')));
        $products = $this->paginate();
テンプレに
{$paginator->sort('名前','name')}
{$paginator->sort('name')}だと動かない?!

隠し属性フィルタを追加する

文字列検索を追加する

文字列検索を拡張する

フォーラムへ投稿する予定の質問

HABTMなアソシエーションで期待したpaginateができません

はじめて投稿します。

productsとcategoriesにHABTMなアソシエーションを設定しました。
CategoriesProduct.category_id' = 1となるレコードをページングを使って表示したいのですがうまくいきません。
find()では、中間テーブルを取得できているのに、

    function index2() {
        $this->Product->bindModel(array('hasOne' => array('CategoriesProduct')));
        $products = $this->Product->find('all',array('conditions'=>array('CategoriesProduct.category_id' => 1)));
        pr($products);
        $this->set('products', $products);
    }

paginate()では中間テーブルが取得できずUnknown columnのエラーが出てしまいます。

    function index3() {
        $this->Product->bindModel(array('hasOne' => array('CategoriesProduct')));
        $products = $this->paginate('Product',array('CategoriesProduct.category_id' => 1));
        pr($products);
        $this->set('products', $products);       
    }

動作するように無理やり書いてみましたが、根本的に何か間違ってるような...。

    function index4() {
        $this->Product->bindModel(array('hasOne' => array('CategoriesProduct')));
        $products = $this->paginate('CategoriesProduct',array('CategoriesProduct.category_id' => 1));
        foreach($products as $key => $value){
            $product_id = $products[$key]['CategoriesProduct']['product_id'];
            $product_data = $this->Product->read(null, $product_id);
            $products[$key]['Product'] = $product_data['Product'];
        }
        pr($products);
        $this->set('products', $products);
    }

詳しくはこちらに書いておきました(長文注意)
http://d.hatena.ne.jp/iphlox/20090612/1244780490
http://d.hatena.ne.jp/iphlox/20090615/1245033086
http://d.hatena.ne.jp/iphlox/20090618/1245296807

何かアドバイスでもいただければありがたいてす。
宜しくお願いします。