- 締切済み
CakePHP2でのfindについての質問
CakePHP2で、findで得た結果をリストでまとめたいと思っています。 さらにその結果をアソシエーション先の大項目でまとめたいです。 言葉ではうまく伝えられないので、以下に例を示します。 例)ユーザーが好きなワインを複数登録し、 「原産国アメリカが6本」「原産国フランスが7本」 のように一覧で国ごとに数をまとめ、 さらにワインの詳細も見れるようにしたいです。 ■Userテーブル カラム:id,ユーザー名 hasMany:好きなワインテーブル ■ワインテーブル カラム:id,ワイン名,kuni_id belongsTo:国テーブル hasMany:好きなワインテーブル ■国テーブル カラム:id,国名 hasMany:ワインテーブル ■好きなワインテーブル カラム:id,user_id,wine_id belongsTo:Userテーブル、ワインテーブル 以上のようなテーブル構成、アソシエーションで、 ユーザーのマイページで、自分が好きなワインに登録した物を ・原産国フランス7本 ・原産国アメリカ6本 のように原産国でまとめ、さらにワインの詳細も見れるようにするには どのような方法を用いれば可能でしょうか? 「好きなワインテーブル」からユーザーidでfindすれば 単純に一覧は取れるのですが、それを国ごとにまとめる方法が分からず困っています。 もし分かる方いらしたら教えてください。 宜しくお願い致します。
- みんなの回答 (1)
- 専門家の回答
みんなの回答
- mpro-gram
- ベストアンサー率74% (170/228)
集計データと詳細データは同時にはとれないので、個別にfind が必要です。 集計データを取る上で、findしたいmodelにたいして group化したいtableのカラムが直接連結されない場合は結構面倒です。 とりあえず、取り出したいデータのsql文を作ってみる select User.id,User.name , Kuni.id,Kuni.name , count(*) wine_count from users as User left join users_wines as UserWine on User.id = UserWine.user_id left join wines as Wine on Wine.id = UserWine.wine_id left join kunis as Kuni on Kuni.id = Wine.kuni_id where User.id = 1 group by Kuni.id order by wine_count desc ; ※注: MySQLやSQLiteでは、group化指定カラム以外でも一意に決まるなら、直接select句にいれても問題ない。postgreSQL など他のデータベースでは、User.id,User.nameやKuni.nameのカラムもgroup by句に必要 ※ このまま、query メソッドで上記SQL文を発行して取り出すのも一つの手です。 findメソッドにこだわるなら、全部left join で連結可能なので、find の第2引数optionに joins でtable指定すると良さそうです。この場合 recursive は -1 として、association 設定をoffにしてからfindメソッドを実行します。 <?php $options = array( 'joins'=> array( array( 'table'=>'users_wines', 'alias' => 'UsersWine' , 'type' => 'LEFT' , 'conditions' => array( ' User.id = UserWine.user_id ', /* on句の 結合条件 */ ), ), array( 'table'=>'wines', 'alias' => 'Wine' , 'type' => 'LEFT', 'conditions' => array( ' Wine.id = UserWine.wine_id ', /* joinsで指定している他のtableのalias名が使える */ ), ), array( 'table'=>'kunis', 'alias' => 'Kuni' , 'type' => 'LEFT', 'conditions' => array( ' Kuni.id = Wine.kuni_id ' ), ), ), 'conditions' => array( 'User.id =' => 1 ), 'group' => array( 'Kuni.id', 'User.id','User.name','Kuni.name' ), 'fields' => array( 'Kuni.id','Kuni.name' , 'count(*) as wine_count', User.id', 'User.name' ), 'order' => array( 'wine_count desc' ), ); $this->User->recursive = -1; $data = $this->User->find('all', $options); debug($data); ※ wine_count カラムには、モデル名が付けられないので、モデル名 0 に格納されます テーブル名モデル名は適当に入れたので、細かい打ち間違いはご容赦願います。