■テーブル構成(テーブル名|フィールド)
users|id,name
addrs|id,users_id,zips_id
zips|id,pref,address
■やりたいこと
ユーザーテーブル(users)と住所テーブル(addrs)を結合し、住所テーブルを郵便番号テーブル(zips)と結合して、住所を取得する
■イメージする配列結果
[Users]=>Array(
[id]=>1
[name]=>aaa
)
[Addrs]=>Array(
[0]=>Array(
[id]=>1
[zips_id]=>1
[pref]=>都道府県名
[address]=>市区町村名
)
)
単純にユーザーテーブルと住所テーブルを結合するだけならhasManyで出来るのですが、結合先が更に別のテーブルと結合している、というコードの書き方が分かりません。
上記のソースはあくまで質問上、簡略化する為に記載しています。
テーブル構造そのものを変更する等は無しでお願いします。
お分かりの方はアドバイスをお願いします。なお、CakePHPは1.3.2を使用しています。
詳しい利用方法が分からないので、この場合利用できそうな方法を2つあげておきます。
1.通常のアソシエーションを利用する方法
この例では、addrsテーブルがusersとzipsテーブルの関連テーブルになっています。
その場合、addrsテーブルを軸に操作すれば、取得できます。
具体的には、
Addr belongsTo User
Addr belongsTo Zip
を定義した上で、
$this->Addr->find('all', <条件>);
として記述できます。条件には、Userの項目もAddressの項目も指定できます。
2.joinを扱う方法
1の方法だと扱えない場合はコードとしては煩雑になりますが、明示的にjoinしてあげることで対応できます。
参考:http://book.cakephp.org/ja/view/78/Associations-Linking-Models-T...
3.7.6.8 Joining tablesの項を見てください。
この場合だと、こんな感じでかけます。
$options['joins'] = array(array('table' => 'addresses', 'alias' => 'Address', 'type' => 'LEFT', 'conditions' => array('User.id = Address.user_id')), array('table' => 'zips', 'alias' => 'Zip', 'type' => 'LEFT', 'conditions' => array('Zip.id = Address.zip_id'))); $options['fields'] = array('User.id', 'User.name', 'Zip.prefecture', 'Zip.address'); $result = $this->User->find('all', $options); print_r ($result);
これで、以下のようなデータが取得できます。
Array ( [0] => Array ( [User] => Array ( [id] => 1 [name] => aaa ) [Zip] => Array ( [prefecture] => xxx [address] => 123 ) ) [1] => Array ( [User] => Array ( [id] => 1 [name] => aaa ) [Zip] => Array ( [prefecture] => yyy [address] => 123 ) ) [2] => Array ( [User] => Array ( [id] => 2 [name] => bbb ) [Zip] => Array ( [prefecture] => xxx [address] => 456 ) ) )
何かの参考になれば。
ありがとうございます。思い通りに出来ました。