質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.32%

MySQL(cakephp)のクエリーの書き方について

受付中

回答 0

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 456

Nanohana

score 108

CakePHP2.9.1でhasAndBelongsToManyを活用したタグ機能を作成しています。
タグが付いている画像を表示するためのスクリプトを書いています。
・photosテーブル・・・画像のデータが入っている
・belongstoでuserテーブルをアソシエーションしており、投稿者データはuserテーブルに入っている
・Tdtagテーブル・・・タグのテーブル
・photos_tdtagsテーブル・・・アソシエーションのためのテーブル

イメージ説明

下記のようなスクリプトで /photos/tag/かもめ
とURLを指定し、「かもめ」のタグが付いている画像を表示させたいのですが、
userテーブルをアソシエーションして持ってくるユーザーデータがランダムなデータになっており、
きちんとphotoテーブルのuser_idカラムに入っているuserデータを持ってきてくれません。
どうすれば上手くいくでしょうか...

Photo.php(モデル)

public $belongsTo = 'User';
public $hasAndBelongsToMany = array(
        'Tdtag' => array(
        'className' => 'Tdtag',
        'order' => 'tag'
                 )
                   );


public function findAllByTags($tags = array(), $limit = 50, $page = 1, $criteria = null){
        if(count($tags) <= 0){
        return 0;
                     }
        if(!empty($criteria)) {
        $criteria = 'AND'.$criteria;
                     }

        $prefix = $this->tablePrefix;
        $offset = $limit * ($page-1);
        $posts = $this->query(
        "SELECT Photo.id,
        Photo.created,
        Photo.dir,
        Photo.user_id,
        Photo.filename,
        User.id,
        User.handlename,
        COUNT(DISTINCT tdtags.tag) AS uniques
        FROM
        {$prefix}photos Photo,
        {$prefix}photos_tdtags photos_tdtags,
        {$prefix}tdtags tdtags,
    {$prefix}users User
        WHERE Photo.id = photos_tdtags.Photo_id
        AND User.id = photos.user_id
        AND tdtags.id = photos_tdtags.tdtag_id
        AND tdtags.tag IN ('".implode("', '", $tags)."') $criteria
        GROUP BY photos_tdtags.Photo_id
        HAVING uniques = '".count($tags)."'
        ORDER BY Photo.created DESC
        LIMIT $offset, $limit"
        );

        return $posts;
        }

PhotosController.php (タグから画像を引っ張ってくるページを表示するためのスクリプト)

public function tag($tag = null) {
            $tags = array();
            App::uses('Sanitize','Utility');
            $this->Sanitize = new Sanitize;

            if(isset($this->params['pass'])){
            $i=0;
            $title="タグ:";
            foreach($this->params['pass'] as $tag):
            $this->Sanitize->paranoid($tag, array(' '));
            $tags[] = $tag;
            if($i==0){
                $title=$title.$tag;
                }else{
                    $title=$title.",".$tag;
                }
                $i++;
            endforeach;

                                }  
            $paging['url'] = '/photos/tag'. implode('/', $tags);

            $params = array(
                'conditions' => array(
                   'Tdtag.tag' => $tags,
                )
             );

             //paging['total'] = $this->Photo->find('count', $params);
            $paging['total'] = $this->Photo->findCountByTags($tags);
            //debug($paging['total']);
            if($paging['total'] > 0){
             //$posts = $this->Photo->findAllByTags($tags);
             $this->set('photo',$this->Photo->findAllByTags($tags));
             debug($this->Photo->findAllByTags($tags)); ★ここのデバッグ結果を下に記載しています
             $this->set('company',$title);
            $this->render('/Companys/company');

                         }else {
            //タグの記事が無い場合の処理。記事が見つかりませんでしたみたいな。
            //exit;
            }
            }

帰ってきたデバッグ結果

array(
    (int) 0 => array(
        'Photo' => array(
            'id' => '14065',
            'created' => '2018-01-16 20:19:26',
            'dir' => '/files/aaa/',
            'user_id' => '1',
            'filename' => '/xxx.jpg',
        ),
        'User' => array(
      'id' => '538', 
            'handlename' => '前原誠司', 
            'url' => ''
        ),
        (int) 0 => array(
            'uniques' => '1'
        )
    )
)

UserテーブルのID=1は、安倍晋三にも関わらず、帰ってくるユーザーデータはUserテーブルからランダムなものが帰ってきてしまっています。
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正の依頼

  • asahina1979

    2018/03/25 13:14

    見てもらうならインデントをちゃんとしよう

    キャンセル

  • Nanohana

    2018/03/25 14:13

    すいません、インデントを修正しました。

    キャンセル

  • m.ts10806

    2018/04/25 10:28 編集

    あまりインデント変わっているように見えますが・・・。プレビュー確認しながらしましょう。または何かしらフォーマッターを使ってください。

    キャンセル

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.32%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る