CakePHPで複数アソシエーションの書き方について相談です。


■テーブル構成(テーブル名|フィールド)
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を使用しています。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2010/07/22 20:46:15
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:tdoi No.1

回答回数174ベストアンサー獲得回数75

ポイント100pt

詳しい利用方法が分からないので、この場合利用できそうな方法を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
                )
        )
)

何かの参考になれば。

id:k27w

ありがとうございます。思い通りに出来ました。

2010/07/22 20:46:05

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません