読者です 読者をやめる 読者になる 読者になる

Life is Really Short, Have Your Life!!

ござ先輩の主に技術的なメモ

CakePHP2.xのContainableの仕組みはよくわからない・・

Deepなアソシエーションを組もうとするとバインドされないことが多くて困ってる。

注文明細は商品にBelong、商品は仕入先とカテゴリBelongしてるとする。

<?php
$注文明細->contain(array('商品'=>array('仕入先','カテゴリ'));

商品までは取れるのだが、仕入先とカテゴリが全く無視されてしまう。A→Bまではいけるが、A→B→Cの「C」がバインドされない。B→CはAから見てHasManyだからB→CはHasManyでアソシエーション組めっていうのもなんかキモイ。

結構こういうDeepなJoin、つまり元となるモデルと直接Joinできるわけではなく数珠つなぎにJOINする挙動の整合性が分からないのでめんどくなってSQLを投げるんだけど、where文の組み立てがだるい時にCake側で何とかしたいなぁといつも悩む。とりあえず今日もSQLをQueryで投げる。

いつか振り返るためのメモ。

追記 2013/07/05 13:40

天才が海の向こう側にいた。こいつ天才。以下コードを抜粋して掲載。

Using bindModel to get to deep relations | Mark Story

<?php
$this->unbindModel(array(
    'belongsTo' => array('Category')
));
 
$this->bindModel(array(
    'hasOne' => array(
        'Category' => array(
            'foreignKey' => false,
            'conditions' => array('Category.id = Item.category_id')
        ),
        'Section' => array(
            'foreignKey' => false,
            'conditions' => array('Section.id = Category.section_id')
        )
        'Division' => array(
            'foreignKey' => false,
            'conditions' => array('Division.id = Section.division_id')
        )
    )
));
$result = $this->find('first', array(
    'conditions' => array('Item.id' => $id),
    'contain' => array('Category', 'Section', 'Division'),
    'fields' => array('Division.id')
));

あとでこっそりGistに入れておくんだ・・・!

すげーすげー、こうやってバインドすれば一度に全部のテーブルがJOINされるみたいで、SQLも1発でいいんだ。Containすると数珠つなぎでSQL投げるからなー。