• 締切済み

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すれば 単純に一覧は取れるのですが、それを国ごとにまとめる方法が分からず困っています。 もし分かる方いらしたら教えてください。 宜しくお願い致します。

  • PHP
  • 回答数1
  • ありがとう数0

みんなの回答

  • mpro-gram
  • ベストアンサー率74% (170/228)
回答No.1

集計データと詳細データは同時にはとれないので、個別に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 に格納されます テーブル名モデル名は適当に入れたので、細かい打ち間違いはご容赦願います。

関連するQ&A

  • [CakePHP]複数テーブルのアソシエーション

    CakePHPについて質問です(Ver.2.2)複数テーブルのアソシエーションについてなのですが、下記のようなアソシエーションは可能でしょうか? [使用テーブル] Post、Recommend、UserMaster、UserDetail [結合キー] (1)Post.id = Recommend.post_id (2)User.id = Post.user_id (3)User.id = UserDetail.user_id つまり、Post.php内にてPost以外で紐づいているテーブル同士を結合が可能かどうかを知りたいです。((1)(2)はPostテーブルと紐づいているが、(3)はPostテーブル以外同士で紐づいている) 下記方法にて(1)(2)は実現できたのですが、(3)の方法が見つかりませんでした。 -- class Post extends AppModel { $belongsTo = array('User'); $hasOne = array('Recommend'); (略) -- 不明点あればご説明します。どうぞよろしくお願いします。

    • ベストアンサー
    • PHP
  • cakePHPでアソシエーションが出来ない

    2つのモデル間でのhasMany-belongsTo のアソシエーションが出来ずに困っています。(cakephpのバージョンは2.4.4, php5.4,16, mysql 5.5.32) 2つのモデルは、コントローラーからそれぞれのindex()で表示できますが、外部キーで相手を指せていないようです。親からのfind('all')で、親の値しか変数に入ってきません。表記や考え方がおかしいのかもしれません。規約には沿っているつもりですので外部キーを入れないアソシエーションの指定(両モデルに対して)も試してみましたがダメでした。以下に、2つのテーブルとモデルを書きます。おかしいところを指摘して頂けると助かります。 ・GiiGestモデルにGiiPostモデルが多数ぶら下がっている構造です。(1:n) GiiGestモデル テーブル名:gii_gests  フィールド:id 主キー autoincrement ,neme varchar(128) ファイル名:gii_gest.php クラス名:GiiGest <?php class GiiGest extends AppModel{ // public $hasMany = 'GiiPost'; <- これだけでもダメでした。 public $hasMany = array( 'GiiPost' => array( 'className' => 'GiiPost', 'foreignKey' => 'gii_gest_id', <- ここいいのか疑問です? ) ); } GiiPostモデル テーブル名:gii_posts  フィールド:id 主キー autoincrement, gii_gest_id int not null ,comment varchar(255) ファイル名:gii_post.php クラス名:GiiPost <?php class GiiPost extends AppModel{ // public $belongsTo = 'GiiGest'; <- これだけでもダメでした。 public $belongsTo = array( 'GiiGest' => array( 'className' => 'GiiGest', 'foreignKey' => 'gii_gest_id' ) ); }

    • ベストアンサー
    • PHP
  • Cakephpでランキング機能の作成方法について。

    Cakephpでランキング機能の作成方法について。 Cakephpで、お気に入り数順のランキング機能を作りたいと考えています。 以下のような構造でランキングを表示させたいのですが、 やり方が分からず困っています。 ■システム概要 コーヒーの紹介サイトです。 様々なコーヒーが登録されており、ユーザーは任意のコーヒーをお気に入り登録できます。 Coffeeテーブル id , name Userテーブル id , name Favoriteテーブル id , coffee_id , user_id 現在、ランキングを表示させたいページであるindex.ctpには、$this->Coffee->find();でCoffeeの情報を表示させています。 アソシエーションでUserテーブル、Favoriteテーブルの情報も取れていますが、これをお気に入り数順にソートするやり方がわかりません。宜しくお願いします。

    • ベストアンサー
    • PHP
  • CakePHPのアソシエーションがうまくいかず困っています。

    CakePHPのアソシエーションがうまくいかず困っています。 以下の3つのテーブルがあります。 [Table_A] id_a id_b name_a [Master_B] id_b name_b [Table_C] id_c id_a name_c Table_Aを中心にアソシエーションを設定しようと思い、modelを以下のように設定しました。 [Model A] class A extends AppModel { public $name = 'A'; public $useTable = 'Table_A'; public $primaryKey = 'id_a'; public $hasOne = array( 'C' => array('className' => 'C', 'foreignKey' => 'id_c' ) ); } [Model B] class B extends AppModel { public $name = 'B'; public $useTable = 'Table_B'; public $primaryKey = 'id_b'; } [Model C] class C extends AppModel { public $name = 'C'; public $useTable = 'Table_C'; public $primaryKey = 'id_c'; } そして、Controllerを以下のように設定しました。 [Controller A] $a = $this->A->find('all'); Controller Aでfindした結果、name_aとname_cの取得には成功しました。 そこでname_bも取得しようとしたのですが、どのようにアソシエーションを設定すればよいか、わかりません。 テーブルの項目は固定であり変更できないため、なんとかこれでアソシエーションを設定したいと思っています。 マニュアルやウェブサイトを調べたのですが、わかりませんでした。 ご教授のほどよろしくお願いいたします。

    • 締切済み
    • PHP
  • CakePHP recursiveプロパティの使い

    大分類、中分類、小分類のテーブルを作っており、大分類・中分類間、中分類、小分類間は、それぞれのModelでbelongsToを用いてアソシエーションができていることは確認できております。 小分類のindex.ctpで、大分類・中分類・小分類の各項目を表示する表を作成しようと考えており、小分類のModelで、下記の記述をしました。 $this->set('「変数名」',$this->「小分類のModel名」->find('all',array('recursive'=>2))); しかし、その結果、 「Notice (8): Undefined index: 「大分類のModel名」 [APP/View/…/index.ctp, line 12]」 というエラーが戻ってきてしまっています。 recursiveプロパティで2を選択おけば、「小分類」のModelからでも、「中分類」のModelを経由してbelongsToでつながっている「大分類」のデータを拾ってくることができると思っていましたが、そうはいかなかったのだと思います。 どなたか、ご教示頂けないでしょうか。 よろしくお願い致します。

    • 締切済み
    • PHP
  • cakephpのアソシエーションについて

    cakephp について勉強中です。 初心者なのでぜひ教えていただきたいのですが、 ・[Profile]と[Image]というテーブルがあり、ProfileについてImagesとのアソシエーションが  hasmanyなのですが、 コントローラーで  $datas = $this->Profile->find("all"); $this->set("datas",$datas); とした場合、view側でProfileのデータもImageのデータも表示されるにはどうしたらよいのでしょうか。 今は <?php foreach($datas as $data):?> <?php echo $data['Profile']['id']; ?> <?php echo $data['Image']['id']; ?> <?php endforeach; ?> とやっていますが、Imageテーブルのデータが出ません。 大変基本的なことだとは思いますがご指導いただければと思います。よろしくお願いします。

    • ベストアンサー
    • PHP
  • cakephpでのsaveについて

    テーブルに登録ユーザカラムと、変更ユーザカラムを設けています。 cakephpでは登録日、変更日を自動で設定してくれますが、同様に登録ユーザ、変更ユーザを設定する方法はないでしょうか? ---- また、以下のように複数レコードをsaveしています。 idのあるなしで、insertとupdateを切り分けが行われますが、その際に同様に登録ユーザ、変更ユーザを切り分ける方法ありませんでしょうか? foreach($records as $record){ $this->create(); $this->save($record); } 登録ユーザと変更ユーザの切り分けは以下のようにやろうと考えていますが、もっと良い実装があるのではと考えています。 foreach($records as $record){ $this->create(); if(isset($record['id']){ //id値があればupdateなので更新ユーザ $record['modified_user']=$user_id }else{ //id値がなければinsertなので登録ユーザ $record['created_user']=$user_id } $this->save($record); } 他の方が更新ユーザ、登録ユーザをどう設定しているのか、またスタンダードな方法やもっと良い実装方法あれば、ご教授ください。よろしくお願いします。

    • 締切済み
    • PHP
  • cakephpの質問2つ

    2つ質問させてください。 cakephpで、ホームページの左に項目を追加したいのですが (ホームページによくあるホームページ内リンク、ホームページ内の検索フォーム)、 layoutで指定できるのは、調べた限り、$title_for_layoutと$content_for_layoutだけでした。 当然、コントローラで取得した値は、メインの真ん中にしか、適応できず、左に適応させると、 今度はメインの真ん中の処理ができなくなってしまいます。 $content_for_layoutなどの変数(例:$sub_content_for_layout)を別個作る必要があるのでしょうか。また、そうであれば、 どのファイルに追記する必要がありますか。 コントローラで、ある変数を条件にfind()で1件だけレコードを取得して、そのデータをviewで使いたいのですが、 setした$dataの構造が確認できず、$arr['id']などの情報が取得できません。$data['テーブル名']としてviewに書くと、 すべてのカラムがAと表示され、うまくいきません。 controller: public function index(){ $cond = param['url']['name']; $data = $this->Table->find($cond); } view hoge.ctp: $arr = $data['Table']; foreach($data as $key){ echo $arr['id']; echo $arr['name']; echo $arr['phone']; } 以下、html~ 本やネットなどで調べましたが、当該情報が得られませんでした。お手数ですが、ご回答願えないでしょうか。

    • 締切済み
    • PHP
  • 複数のデータを選択し結果をcsvに保存し処理

    現在複数のデータを選び、その結果をcsvで保存することを考えています。 例えば 好きな国を選んで、コメントを書いてください。 アメリカ イギリス フランス スペイン ポルトガル ブルガリア ・ ・ ・ と100ヶ国表示します。チェックボックスで好きな国を任意の数だけ選びそれをcsvに保存したと仮定します。 data.csv ============= ユーザー名,好きな国,コメント ユーザA,アメリカ,イギリス,スペイン,行きました。 ユーザB,アメリカ,ブルガリア,イギリス,ポルトガル,好きです。 ユーザC,イギリス,コメントです。 ========================= これを読み出す場合、列が沢山あるため $Data = file("data.csv"); for($i=0;$i<sizeof($Data);$i++){ $line = explode(",",$Data[$i]); =====ここの処理がわかりません。=== list($u_name, $kuni, $kuni, $kuni, $kuni, $kuni, $kuni, ・・・・・・・$com = $line; if($u_name = $_GET['u_name']) echo "$u_nameの好きな国リスト<P>"; echo " $kuni<BR>"; } } とlistで変数に配分することができません。 このようなユーザーが何件登録するかわからない場合のCSVの処理はどのようにすればよろしいのでしょうか? ユーザーの名前を利用してu_name.txtを作成し中にデータを書き込んだほうが良いのでしょうか? このような複数選択されて何件登録されるかわからない(フィールドが何列になるかわからない)データの保存、処理はどのように行うのが定石なのでしょうか? 恐縮ですがお力をお貸し頂ければ幸いです。

    • ベストアンサー
    • PHP
  • AUTO_INCREMENTの扱いについて

    MySQL 5.6を使用しています。 ユーザーテーブルがあるとします。 ユーザーテーブルにある「ユーザーID」はinsert時にAUTO_INCREMENTで自動採番されます。 ユーザーテーブルの別のカラムで「作成ユーザID」というカラムがあります。insertしたユーザーのユーザーIDを保持するカラムです。 すでにユーザーテーブルにいるユーザー(管理者)がinsertした場合はいいのですが、 自信で自分のユーザーを登録できる機能もあります。 その場合、まだ作成されてないユーザID(AUTO_INCREMENTで自動採番されるユーザーID)をどうやって参照したらいいでしょうか?

    • ベストアンサー
    • MySQL

専門家に質問してみよう